Этот тип кода является неправильным использованием потока (и неправильным использованием свойства FreeOnTerminate
), поскольку вызывающий код блокируется в ожидании завершения потока, поэтому нет никакой причины иметь поток на первом месте..
С учетом сказанного по умолчанию TClientSocket
работает в неблокирующем режиме, который использует оконные сообщения для запуска событий сокета.Поток, который активирует сокет, должен иметь цикл сообщений, чтобы эти уведомления сокета могли быть получены и отправлены правильно.В противном случае вам придется использовать сокет в режиме блокировки, как сказал Мартин.
Обновление:
Показанный вами обновленный код просто неверен на нескольких уровнях,Поток все неправильно.Использование TClientSocket
неверно.Учитывая блокирующую природу вашей функции GetSocketData()
, нет необходимости вообще использовать какие-либо потоки (тем более, что вы заявили, что GetSocketData()
сам вызывается в потоке, поэтому дополнительная многопоточность избыточна), и вам следуетвообще не беспокоиться о событиях TClientSocket
, особенно о событии OnRead
, в частности, поскольку он вообще НЕ вызывается в режиме блокировки (что является причиной вашей проблемы!).
Вы сделаливаш код НАМНОГО сложнее, чем нужно.Вместо этого используйте что-то вроде этого:
function GetSocketData(const IP, Port: PChar): PChar; export; cdecl;
var
ClientSckt: TClientSocket;
//other params
begin
Result := nil;
try
/init params/
CoInitialize(nil);
try
ClientSckt := TClientSocket.Create(nil);
try
ClientSckt.ClientType := ctBlocking;
ClientSckt.HostAndAddress := IP;
ClientSckt.Port := Port;
ClientSckt.Open;
try
// send the special command to the port from here
// read all data and interpret from here
Result := BlockAlloc(...);
finally
ClientSckt.Close;
end;
finally
ClientSckt.Free;
end;
finally
CoUninitialize;
end;
except
end;
end;