2

わかりました、私は TClientSocket クラスと Threads を使用して、ホストのリストと同時に動作しています。それはすべて問題ありませんが、しばらくすると、すべてのスレッドが ReceiveBuf 呼び出しにスタックすることに注意し始めました...たとえば、100 個のホストをチェックするために 10 個のスレッドを開くと、正常に開始されますが、しばらくするとすべてのスレッドがスタックします。何らかの理由で、一部のホストはこの 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 コードの詳細を表示する編集:: 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;
4

1 に答える 1

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

とにかく、助けようとした人たちに感謝します!

于 2013-05-21T17:33:15.207 に答える