Почему события OnClientConnect и OnClientError не срабатывают для TServerSocket в режиме блокировки

Я использую Embarcadero RAD studio C++ Builder XE для создания приложения C++. Приложение использует динамически созданный компонент TServerSocket в режиме блокировки. Я создаю класс, производный от TServerClientThread, который предоставляет собственный метод ClientExecute(). Этот класс создается с помощью TServerSocket обработчика событий OnGetThread, который я реализовал. Я назначаю обработчики событий для OnAccept, OnClientConnect, OnClientDisconnect и OnClientError. Внутри моего класса потока я использую класс TWinSocketStream для чтения и записи из соединения сокета.

Я использую пользовательский написанный класс (производный от TComponent), который создает TServerSocket, а обработчики событий, которые я назначаю, являются функциями-членами этого класса.

Мои события OnAccept и OnClientDisconnect срабатывают, но ни одно из событий OnClientConnect и OnClientError никогда не срабатывает. Это нормальное поведение для этого компонента? Все, что я читал об этом компоненте, предполагает, что ВСЕ события будут срабатывать для TServerSocket в режиме блокировки, и я просто не могу понять, почему эти события не сработают. Есть ли что-то еще, что мне нужно сделать, или эти события просто не работают в режиме блокировки? Возможно ли, что использование экземпляра TServerSocket в качестве члена другого производного класса TComponent вызывает какие-то проблемы?


person mathematician1975    schedule 15.04.2013    source источник


Ответы (1)


Событие OnClientConnect запускается конструктором TServerClientWinSocket. Объект TServerClientWinSocket создается сразу после вызова события OnGetSocket, когда WinSock принимает новый клиентский сокет, и непосредственно перед вызовом событий OnAccept и OnGetThread. Таким образом, единственный возможный способ, которым OnClientConnect не будет вызываться, - это если вам на самом деле не назначен обработчик.

OnClientError вызывается при сбоях неблокирующих сокетов, а также TCustomWinSocket.SendStream(), TCustomWinSocket.SendBuf() и TCustomWinSocket.ReceiveBuf(). Если вместо этого вы используете TWinSocketStream для ввода-вывода, ни один из этих методов не вызывается им. Вместо этого он вызывает ESocketError исключений при сбое. Если вы не поймаете эти исключения, вызов TServerClientThread просто завершится (после передачи исключения в основной поток для обработки).

person Remy Lebeau    schedule 15.04.2013
comment
Спасибо за Ваш ответ. У меня есть назначенный обработчик OnClientConnect, но я не написал обработчик OnGetSocket, так как понял, что это не обязательно. У меня есть обработчик OnGetThread, но является ли отсутствие обработчика OnGetSocket возможной причиной того, что мое событие не срабатывает? - person mathematician1975; 16.04.2013
comment
OnGetSocket является необязательным и никак не влияет на то, вызывается OnClientConnect или нет. Если у вас есть обработчик, назначенный OnClientConnect, то он должен вызываться, если только TServerSocket в 2010/XE не имеет ошибки, которой нет в других версиях. У меня никогда не было проблем с правильным вызовом OnClientConnect. Я предлагаю вам включить библиотеки отладки в параметрах проекта, чтобы вы могли перейти к исходному коду TServerSocket в ScktComp.pas и выяснить, почему TServerClientWinSocket.Create() не вызывает OnClientConnect при вызове TServerWinSocket.GetClientSocket(). - person Remy Lebeau; 16.04.2013
comment
Я попробую то, что вы предлагаете. Спасибо за помощь. - person mathematician1975; 16.04.2013