2013-05-20 25 views
2

好吧,我正在使用TClientSocket類和線程與主機列表同時工作。這一切都很好,但我開始注意到,在某個時候,所有線程都會陷入ReceiveBuf調用中......如果我打開10個線程,例如檢查100個主機,它將啓動良好,但在某個時間之後,所有線程都會被阻塞,因爲某些原因某些主機無法正確接收此ReceiveBuf調用...我嘗試執行ReceiveLength並檢查接收是否大於0,以調用ReceiveBuf,但仍然無法工作。 我會後下面的原代碼:TClientSocket和線程

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; 
+0

'MySocket'在哪裏被初始化?每個線程都有自己的'TClientSocket'嗎?你對套接字使用阻塞模式還是非阻塞模式?沒有足夠的代碼來診斷您的問題。 –

+0

MySocket在線程類的另一個函數中初始化......每個線程都有自己的TClientSocket。我爲套接字使用了阻塞模式... – user1526124

+0

你能展示更多的線程代碼來顯示線程是如何使用'TClientSocket'的嗎? –

回答

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

無論如何,感謝誰試圖幫助的人!