![]() |
|
Модераторы: Snowy, Poseidon, MetalFan |
![]()
|
|
| Dmitry_177 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
Пишу серверную часть программы, которая будет работать с клиентской частью(их будет несколько и надо так, чтобы они все могли одновременно подключиться к серверу). Вот меня интересует следующий вопрос, после ожидания, т.е. выполнения функции listen, сервер должен создать сокет функцией accept, чтобы произошло подключение до конца.. А если будет несколько подключений? Как быть тогда? Делаю так:
И вот в переменной AcceptedSock тогда будет последний сокет, который был создан функцией accept? Если да, то тогда произойдет сбой с теми сокетами которые были подключены ранее и все потоки которые были созданы будут уже работать с последним.. Вот как мне эти сокеты упорядочить? Создать массив или есть способ лучше? И тоже самое с хендлами потоков, чтобы потом их при отключении правильно закрывать.. |
|||
|
||||
| ama_kid |
|
||||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: нет Всего: 95 |
Я то же самое успешно реализовывал (только на Visual C++), поэтому могу кое-что посоветовать...
У функции CreateThread четвертый параметр - это параметр, передаваемый в созданный поток function ThreadProc(Param: Pointer): DWORD; stdcall; Поэтому, мне кажется, будет лучше передавать принятый сокет непосредственно в поток, чтобы не зависеть от остальных потоков. Что-то типа такого (пишу непосредственно в форум, поэтому могут быть ошибки с типами-указателями, но самое главное - показать идею):
Еще один момент - функцию listen надо вынести за цикл (ибо это можно сделать один раз) и цикл организовать по accept. Приведу, на всякий случай, свой рабочий пример, если что - можешь поразбираться:
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
||||
|
|||||
| Dmitry_177 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
У меня получилось =))) Работает =)))
ama_kid, вместо MySock:=(TSocket^)Param; пишем это: MySock := Param; и все работает.. Выложу пример, если кому будет интересно и заглянет в код и найдет ошибки, прошу сообщить об этом..
и еще странность, по идее мне не нужен id потока, пишу в функции CreateThread вместо idThread это: nil выдает ошибку.. Это сообщение отредактировал(а) Dmitry_177 - 19.3.2007, 08:54 |
|||
|
||||
| ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: нет Всего: 95 |
Dmitry_177
Все-таки правильней между CreateThread (кстати, обрати внимание на функцию BeginThread, лучше использовать её) и CloseHandle применять WaitForSingleObject. Ибо поток к закрытию хендла может не завершиться, а закрытие хендла работающего потока не есть гут. Понятно, что ты сделал это для экономии на переменной хендла, но имхо, на таких вещах не экономят... А вот с idThread - это да, здесь можно было бы сэкономить, но дельфи этого не дает, ибо этот параметр объявлен как var, поэтому в отличие от C++ туда надо передавать адрес реальной переменной.... -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
| dumb |
|
|||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 5 Всего: 158 |
||||
|
||||
| ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: нет Всего: 95 |
Конечно, законная, ибо не запрещенная прямо... Но закрывая хендл потока, теряешь над ним контроль, и в случае его зацикливания (читай - мемори-лика) отсутствует возможность проинформировать об этом разработчика\юзера (с помощью той же WaitForSingleObject)... А при наличии огромной кучи таких потоков (каждый со своим некорректным кодом) это может привести к неопознанным AV. P.S. Конечно, в данном случае вряд ли что-то такое будет, но все-таки закрывать хендл проверенно завершенного потока - это хорошая привычка, которая помогает уменьшить вероятность появления мемори-ликов... -------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
| Dmitry_177 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
Почему не воспользовался select-ом, потому что у меня подключение долгое.. т.е. постоянное висит, и нету постоянно обмена данными.. но блин, может и оборваться же это соединение.. может с какой-то периодичностью посылать какой-то пакет чтоб клиент немедленно ответил на него для проверки связи?
И еще вопрос, вот я посылаю в клиенте и принимаю в этом сервере переменную типа integer, т.к. мне так удобней, т.к. можно воспользоваться case .. of, а многие другие протоколы, тот же smtp передают строку.. вот с чем лучше работать со строкой или с integer? с integer более наглядный код, а со строкой одни условия будут.. насчет BeginThread обращал внимание.. учту что ей лучше воспользоваться, но чем она лучше? |
|||
|
||||
| ama_kid |
|
||||||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: нет Всего: 95 |
А, теперь понятно, тогда нормально...
Это как тебе удобнее, ты в любом случае передаешь буффер, а как ты интерпретируешь этот буфер - твое дело...
BeginThread - это функция над М$-овсокой _beginthread. О том, чем она лучше, можешь почитать MSDN KB. Упрощенно говоря, при использовании CreateThread могут быть небольшие утечки памяти... -------------------- самурай без меча подобен самураю с мечом, но только без меча |
||||||
|
|||||||
| Dmitry_177 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 418 Регистрация: 22.9.2006 Репутация: нет Всего: нет |
Честно говоря сам не знаю почему как же это работает, но работает.., если всем потокам я передаею параметром адрес одной и той же переменной, хранящей хэендл самого последнего созданного гнезда.. И почему-то работает это, проверял, подключался к нему несколькими компьютерами и все он принимает с любого компьютера, если они все подключены будут..
|
|||
|
||||
| dumb |
|
|||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 5 Всего: 158 |
как бы там ни было, передавай не указатель, а непосредственно TSocket - это ж обычный dword по сути.
|
|||
|
||||
![]()
|
| Правила форума "Delphi: Сети" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |