2013-03-11 1 views
1

Я пытаюсь использовать компонент 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 в неблокирующем режиме

ответ

2

TClientSocket В режиме блокировки используется скрытое окно для приема событий сокета. Если вы используете неблокирующий TClientSocket в TThread, тогда вы должны реализовать цикл сообщений внутри вашего метода TThread::Execute(), чтобы отправить эти сообщения в окно сокета. Кроме того, будучи основанным на окнах, это также означает, что сообщения сокета отправляются в поток, который фактически создает окно сокета, поэтому вы должны убедиться, что вы открываете TClientSocket изнутри вашего метода TThread::Execute().

BTW, BCB6 поставляется с Indy 8, что является альтернативой. Вы также можете установить последнюю версию Indy или даже другую стороннюю библиотеку, такую ​​как ICS или Synapse.

+0

Спасибо за этот ответ, это очень полезно. Достаточно ли было бы передать основной указатель TApplication на мои классы потоков и вызывать 'ProcessMessages()' на этом указателе периодически из 'Execute()' или я должен эксплицитно использовать 'GetMessage()', 'DispatchMessage()'? – mathematician1975

+0

Не используйте 'ProcessMessages()', 'GetMessage()'/'DispatchMessage()' loop в порядке. –

+0

Или используйте вместо этого 'TClientSocket' в режиме блокировки, тогда вам вообще не нужно беспокоиться о сообщениях. –