Я пытаюсь использовать компонент Borlands TClientSocket
в неблокирующем режиме внутри многопоточного приложения C++ Windows. Я создаю несколько потоков (классы, полученные из TThread
), каждый из которых создает свой собственный объект TClientSocket
. Затем я назначаю функции-члены класса потока действовать как обработчики событий для событий OnConnect
, OnDisconnect
и OnSocketError
событий сокета. Проблема, которая возникает у меня здесь, заключается в том, что всякий раз, когда я вызываю функцию TClientSocket::Open()
из функции TThread::Execute()
, событие OnConnect
никогда не срабатывает. Однако, когда я вызываю функцию Open()
из потока VCL перед вызовом вызываемой функции TThread::Execute()
, все события срабатывают, и я могу использовать комбинацию потоков. Теперь я ничего не читал в документации, в которой говорится, что TClientSocket
не должен использоваться в неблокирующем режиме при использовании внутри потока, но мне кажется, что, возможно, что-то не так концептуально в том, как я пытаюсь использовать этот класс. Документация Borland довольно неудовлетворительна по этому вопросу, и эти компоненты теперь устарели, поэтому надежной информации трудно найти. Несмотря на то, что я устарел, я должен использовать их, поскольку нет альтернативы в пакете Builder 6, который у меня есть. Кто-нибудь может посоветовать мне, если есть правильный/неправильный способ использования TThread
и неблокирующий TClientSocket
в комбинации. У меня никогда не возникало проблем с его использованием в составе потока VCL и никогда не было проблем с использованием TServerSocket, и я действительно не могу понять, почему некоторые события не срабатывают.Событие OnConnect не срабатывает при использовании TClientSocket внутри TThread в неблокирующем режиме
1
A
ответ
2
TClientSocket
В режиме блокировки используется скрытое окно для приема событий сокета. Если вы используете неблокирующий TClientSocket
в TThread
, тогда вы должны реализовать цикл сообщений внутри вашего метода TThread::Execute()
, чтобы отправить эти сообщения в окно сокета. Кроме того, будучи основанным на окнах, это также означает, что сообщения сокета отправляются в поток, который фактически создает окно сокета, поэтому вы должны убедиться, что вы открываете TClientSocket
изнутри вашего метода TThread::Execute()
.
BTW, BCB6 поставляется с Indy 8, что является альтернативой. Вы также можете установить последнюю версию Indy или даже другую стороннюю библиотеку, такую как ICS или Synapse.
Спасибо за этот ответ, это очень полезно. Достаточно ли было бы передать основной указатель TApplication на мои классы потоков и вызывать 'ProcessMessages()' на этом указателе периодически из 'Execute()' или я должен эксплицитно использовать 'GetMessage()', 'DispatchMessage()'? – mathematician1975
Не используйте 'ProcessMessages()', 'GetMessage()'/'DispatchMessage()' loop в порядке. –
Или используйте вместо этого 'TClientSocket' в режиме блокировки, тогда вам вообще не нужно беспокоиться о сообщениях. –