Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблемы при работе с Indy [D7, WinXP]


Страницы:   1 2 3 4 5 6 7 8

Cyrax ©   (2006-08-26 18:46:00) 

Столкнулся я с такой проблемой. При использовании компонента TIdTCPClient при отсоединении от сервера не освобождается порт, занимаемый клиентом. Отсоединяюсь я методом Disconnect (пробовал и DisconnectSocket). При каждом очередном соединении клиента ОС выделяет ему новый порт. Если же задать порт клиента самому, то при повторном соединении возникает ошибка - порт то остался занятым...
С TIdTCPServer такой проблемы не возникает.

Что самое интересное, пример работы с TIdTCPServer и TIdTCPClient (IdTCPDemo), скачанный с инета, показывает те же результаты.
На форумах читал, как обсуждали глюки некоторых компонентов Indy.
Так вот, может это очередной глюк? Или отсоединяться (клиенту) нужно как то по-другому?

Правильно ли я понимаю механизм соединения клиента с сервером:
При попытке клиента соединиться с сервером (метод TIdPeerThread.Run на клиенте) на стороне сервера вначале создаётся поток для обслуживания этого клиента. Далее происходит попытка установления связи с клиентом. Событие OnExecute на сервере генерится именно после создания потока. При этом возможна ситуация, когда поток создан, а соединение не установлено. При последующем успешном соединении этого же клиента используется тот же поток.
Если я в чём-то ошибаюсь, прошу меня поправить.
Остаётся непонятно, почему в начале обработчика события OnExecute нужно ставить проверку "if not AThread.Terminated". Что, OnExecute генерится ещё и при завершении работы потока?

Есть у меня и другая проблема. При создании объекта TIdTCPServer присвоил полям OnConnect и OnDisconnect имена обработчиков. Напомню, что я пишу модуль, и никакого интерфейса, а тем более визуальных компонентов, нет. Т.е. все объекты я создаю и инициализирую сам... Так вот, в процессе соединения и отсоединения клиентов сервер генерирует события OnConnect и OnDisconnect соответственно и вызывает мои обработчики этих событий (по крайней мере, должен). С коннектом проблем нет. НО: событие OnDisconnect на сервере не генерируется при отсоединении клиента. Это событие генерируется только при завершении работы сервера (IdTCPServer.Active := false). Как я понял из help'а, оно должно генерироваться при каждом отсоединении клиента. Именно так и происходит в случае с сервером и клиентом, созданных визуально путём установки на форму компонентов (в этом случае все необходимые поля инициализируются нужным образом).

Может я не все нужные поля у IdTCPServer проинициализировал?
Вот моя инициализация клиента:

MaxLineLength := DataMax;        
MaxLineAction := maException;
ReadTimeout := 0;
BoundPort := 0;      // чтобы не возникало проблем с занятым портом
Host := '127.0.0.1'; //  пока для проверки
Port := 6002;          


Инициализация сервера:

DefaultPort     := port;
ThreadMgr      := TIdThreadMgrDefault.Create(id_component);
MaxConnections := ClientsMax;
ListenQueue    := 15;
OnExecute      := onexecute;
OnConnect      := onconnect; // мой обработчик
OnDisconnect  := ondisconnect;  // мой обработчик

_______________________
Дополнительные вопросы:
1. Как в винде посмотреть, какие порты в данный момент заняты и какими прогами (средствами винды, без программирования) + как принудительно освободить занятый порт (естественно, с завершением работы проги).
2. Свойство BoundIP клиента указывает IP компа, на котором можно его запускать ?

_______________________
Напоследок хочу узнать мнение тех, кто работал с Indy. Я пишу модуль, который будет обеспечивать связь клиентов с сервером по TCP/IP. Интерфейс представлен 4-мя функциями: инициализация, отправка, получение и завершение. Так вот, целесообразно ли использовать Indy для этих целей. Или проще напрямую работать с winsock, ведь Indy тоже работат через winsock.


Сергей М.   (2006-08-28 16:28:00) [141]


> Cyrax ©   (28.08.06 16:16) [15]
>
>


Не надо месить в одну кучу сервера и клиента.
Либо ты о сервере, либо о клиенте.
Ты о ком ?


Cyrax   (2006-08-28 16:16:00) [142]


Сергей М. ©   (28.08.06 15:40)

Хорошо, гляну в исходники...

Но следующие вопросы остаются открытыми:
1. При отсоединении клиента (disconnect, либо disconnectsocket) порт не освобождается (см. Cyrax ©   (28.08.06 13:03)).
2. Серверные OnDisconnect'ы не вызываются при отсоединении клиентов (только при завершении работы проги / деактивации сервера).


Сергей М.   (2006-08-28 15:40:00) [143]


> Что значит "циклически" ?


Циклически означает "в цикле".

ты в состоянии заглянуть в исх-ки сервера и проанализировать их ?


> как насчёт дективации сервера ?


А что насчет нее ?
Серверный диспетчер при поступлении "команды" Active := False командует всем работающим своим потокам "Terminate" и ждет пока всесозданные им потоки завершатся.


Cyrax   (2006-08-28 15:15:00) [144]

Что значит "циклически" ? В какие моменты времени ?
И как насчёт дективации сервера ?


Сергей М.   (2006-08-28 13:19:00) [145]


> Циклически после успешного соединения - я так понимаю, генерируется
> однократно после каждого успешного соединения (в рамках
> потока).


Нет, не правильно.
После успешного установления соединения создается новый экз-р TIdPeerThread (или берется уже готовый, ранее созданный и ждущий своего использования в пуле тредпул-менеджера), в контексте которого с этого момента циклически вызывается обработчик OnExecute вплоть до самой "смерти" соединения.


Cyrax   (2006-08-28 13:03:00) [146]

Наконец-то появились нормальные ответы...
[i]
> Slym ©   (28.08.06 06:53)
[/i]
Прибиндивать сокет клиента  - не моя идея, это требование организации (возможность указания порта клиента).
Звучит, конечно, навязчиво... Но всё-таки: когда указываем порт клиента, то при повторном соединении возникает ошибка привязки сокета (без завершения работы проги - соединились, отсоединились, соединились => error). Напрашивается на то, что при отсоединении порт не освобождается... Возможно, отсоединяюсь не так как нужно (см. Cyrax ©   (26.08.06 18:46)). Здесь уже надо знать Indy...
[i]
> Сергей М. ©   (28.08.06 08:35)
[/i]
Циклически после успешного соединения - я так понимаю, генерируется однократно после каждого успешного соединения (в рамках потока).
+ генерируется при завершении потока (после деактивации сервера)?

Как, всё-таки быть с генерацией события OnDisconnect на сервере ? (см. Cyrax ©   (26.08.06 18:46)). Когда это событие должно генерироваться - при отсоединении каждого из клиентов или при завершении работы сервера (при деактивации сервера) ?


Сергей М.   (2006-08-28 08:35:00) [147]


> Cyrax ©   (26.08.06 18:46)


Событие TIdTCPServer.OnExecute возбуждается циклически(а не однократно !) в контексте соответствующего потока TIdPeerThread после успешногоустановления соединения с клиентом.
Проверка флага Terminated нужна для оперативного реагирования на команду деактивации сервера (IdTCPServer.Active := False).


Slym   (2006-08-28 06:53:00) [148]

Клиент вообще не должен думать о своем порте, ему хватает сведений о порте сервера. Порт клиента система сама выделит свободный порт из разрешенного диапазона (>1024)
И зачем прибиндивать клиентский сокет?
при завершении проги, все Хендлы обнуляются, а нулевые освобождаются...


Cyrax   (2006-08-28 00:11:00) [149]

Dmitrij_K, может всё-таки скажешь, в чём я ошибаюсь по поводу механизма...


Cyrax   (2006-08-28 00:09:00) [150]

кто это кому и что должен?
Уточню формулировку: "При очередном соединении клиента ему выделяется порт с номером... Короче, ясно ведь, что имеется ввиду!  Замечу: при условии, что другие проги за это время не занимали и не освобождали портов...
...если не устраивает логика работы...
О какой логике работы идёт речь?
Пока прозвучала только моя версия, которая подтверждается практически. Она меня вполне устраивает... Вопрос в другом - освобождается ли порт?

Насчёт предположений.
Обращаюсь всё-таки к тем, кто знает. Пусть порпавят, если ошибаюсь...
А лезть для этого в исходники - изврат...

Кто нибудь скажет, почему ошибка то возникает !!! (моё предыд. сообщение). Тогда и "споры ни о чём" разрешатся...


Dmitrij_K   (2006-08-27 23:27:00) [151]


> А как насчёт стандартных средств винды (например, брандмауэр
> Windows).

В win нет стандартных средств, Outpost FireWall имхо самый инф
ормативный из тех что я видел

> Или таких ситуаций быть не пожет (при завершении проги порт в любом случае будет освобождён виндой?

имхо так


Ketmar   (2006-08-27 22:34:00) [152]

> [3] Cyrax ©   (27.08.06 22:26)
> при очередном соединении клиента ему должен быть выделен
> тот же порт, что и при предыдущем

кто это кому и что должен? можно пошерстить winsock, если не устраивает логика работы. или своё написать. лично я исходников winsock не видел, и предоположения не делаю. в силу чайниковости, наверное.


Cyrax   (2006-08-27 22:30:00) [153]

По поводу механизма соединения клиента и сервера.
Прошу меня поправить, если невломы писать...


Cyrax   (2006-08-27 22:26:00) [154]

Что порт при очередном соединении не обязательно должен быть тем же самым, я согласен. Но не думаю, что винда будет выделять произвольный порт (из свободных). Наиболее вероятный алгоритм - выделение первого свободного (из определённого диапазона). Если это так, то при очередном соединении клиента ему должен быть выделен тот же порт, что и при предыдущем (если за время между соединениями никакие другие проги не занимали порты).
В подтверждение повторю вопрос, заданный в первом сообщении:
Почему при повторном соединении клиента генерится ошибка, связанная с binding'ом сокета? (это в том случае, когда мы прямо укзываем в клиенте порт привязки)


Файрволом например Outpost FireWall

А как насчёт стандартных средств винды (например, брандмауэр Windows).


> Завершить работу проги

Остроумно. Но я имел ввиду ситуацию, когда прога, которой был выделен порт, при завершении его не освобождает по каким-либо причинам (например, прога глючная). Или таких ситуаций быть не пожет (при завершении проги порт в любом случае будет освобождён виндой) ?


такие вопросы задаются в форуме сети

Вопросы об освобождении портов и механизме соединения клиента с сервером - да. Но о генерации событий OnExecute и OnDisconnect всё-таки в компонентах...


Dmitrij_K   (2006-08-26 21:03:00) [155]

PS такие вопросы задаются в форуме сети


Dmitrij_K   (2006-08-26 21:02:00) [156]

Отвечу на то что могу
Клиенту выдается свободный порт, и необязательно он будет такой же как в прошлый раз (мне всегда так казалось Ж))
Механизм ты понял неправильно.


>  Как в винде посмотреть, какие порты в данный момент заняты
> и какими прогами (средствами винды, без программирования)

Файрволом например Outpost FireWall

> как принудительно освободить занятый порт (естественно,
> с завершением работы проги).

Завершить работу проги

>  Или проще напрямую работать с winsock,

Зависит от твоих знаний


Страницы:   1 2 3 4 5 6 7 8

Наверх

Титульная страница Поиск, карта сайта Написать письмо