TClientSocket和Threads

时间:2013-05-20 20:18:34

标签: multithreading delphi

好的伙计们,我正在使用TClientSocket类和Threads与主机列表同时工作。这一切都很好,但我开始注意,经过一段时间后,所有线程都被卡入了一个ReceiveBuf调用...如果我打开10个线程,例如检查100个主机,它会启动良好,但是过了一段时间后所有线程都会被卡住,因为某些主机因为这个ReceiveBuf呼叫没有回复的原因...我试图做一个ReceiveLength并检查是否接收> 0,调用ReceiveBuf,但仍然无法正常工作。 我将在下面发布原始代码:

function Threads.ReceiveProtocolVersion;
var
   ProtocolVersion: array[0..11] of AnsiChar;
begin
 try
    MySocket.Socket.ReceiveBuf(ProtocolVersion, SizeOf(ProtocolVersion));
    Version:= AnsiString(ProtocolVersion);
   ...//continues but doesn't matter because many threads get stucked in the ReceiveBuf call...
 except
    Terminate; //we terminate thread if raise some exception..

好的,经过一些研究后,我开始尝试这样做:

function Threads.ReceiveProtocolVersion;
var
   ProtocolVersion: array[0..11] of AnsiChar;
   SizeBuf: integer;
begin
 try
    SizeBuf:= MySocket.Socket.ReceiveLength;
    if SizeBuf > 0 then
     begin
       MySocket.Socket.ReceiveBuf(ProtocolVersion, SizeOf(ProtocolVersion));
       Version:= AnsiString(ProtocolVersion);
        ....
     end;
 except
    Terminate; //we terminate thread if raise some exception..

显然,它解决了线程陷入ReceiveBuf调用的问题,但由于某些未知的原因,没有(甚至那些工作正常的)线程进入'if SizeBuf> 0' 。 有什么帮助吗?

//编辑显示更多线程代码:: Thread.Execute是这样的:

procedure MyThread.Execute;
begin
  while not(Terminated) do
    begin
      if SocketConnect then
        begin
          if ReceiveProtocolVersion then
           begin
              DoAuthentication;
            end;
         end;
          MySocket.Close;
          MySocket.Free;
    end;
    Terminate;
end;

SocketConnect功能是:

function MyThread.SocketConnect: bool;
begin
  Result:= false;
  MySocket:= TClientSocket.Create(Nil);
  MySocket.Port:= StrToInt(Form1.Edit1.Text);
  MySocket.ClientType:= ctBlocking;
  MySocket.Host:= Host; //Host is a private variable for thread class
  try
    MySocket.Active:= true;
    if (MySocket.Socket.Connected = true) then
      Result:= true;
  except
    Terminate;
  end;
end;

1 个答案:

答案 0 :(得分:1)

我使用TWinSocketStream解决了这个问题。像这样:

function MyThread.CheckProtocol: bool;
var
  SockStream: TWinSocketStream;
  ProtocolVersion: array[0..11] of AnsiChar;
begin
 try
    SockStream := TWinSocketStream.Create(MySocket.Socket, 3000);
    SockStream.Read(ProtocolVersion, SizeOf(ProtocolVersion));
    RFBVer:= AnsiString(ProtocolVersion);
    ....

我读到使用阻塞模式套接字的正确方法是通过TWinSocketStream发送/接收数据: DocWiki Embarcadero

无论如何,感谢那些试图帮助的人!