我正在以阻塞模式使用TClientSocket / TServerSocket创建TCP客户端/服务器。已经使用telnet构建了概念证明服务器并对其进行了基本功能(接收数据)的测试。在客户端上,将有两个线程,一个用于写入,另一个用于读取。现在,为了测试“发送(或写入)线程”,我正在使用以下代码。但是stream.WaitForData(30000)总是超时。 Delphi帮助说:“在通过套接字连接读取或写入信息之前,请先调用WaitForData”。所以我想知道TWinSockStream如何知道我正在调用WaitForData进行写入而不是读取?

procedure TClientThread.Execute;
var
  stream: TWinSocketStream;
  buffer: string;
begin

  stream := TWinSocketStream.Create(FClientSocket.Socket, 60000);
  try
    while (not Terminated) and (FClientSocket.Active) do
    begin
      try
        //FSendDataEvent is a trigger used for testing purpose
        if FSendDataEvent.WaitFor(1000) = wrSignaled then
        begin
          FSendDataEvent.ResetEvent;

          if stream.WaitForData(30000) then
          begin
            buffer := 'Hello from client';
            stream.Write(buffer, Length(buffer) + 1 );
          end;
        end;
        //Other useful code
      except
        on E:Exception do
        begin
          DebugOutput('TClientThread.Execute: ' + E.Message);
        end;
      end;
    end;
  finally
    stream.free;
  end;

end;


即使删除了WaitForData(),文本也不会照原样发送到服务器。但是以下代码在直接调用时没有任何WaitForData()时可以正常工作。

FClientSocket.Socket.SendText('Hi from client');


那么,将TWinSocketStream与TClientSocket一起使用的正确方法是什么?

任何帮助将不胜感激。

最佳答案

该文档是错误的。 WaitForData()仅适用于阅读,不适用于书写。

对于使用TWinSocketStream写入数据,您在Write()的第一个参数中传递了错误的值,这就是为什么它无法正确发送的原因。第一个参数是无类型的const,因此您需要引用字符串以便传递第一个字符的内存地址,例如:

Stream.Write(Buffer[1], ...);


要么:

Stream.Write(PChar(Buffer)^, ...);

10-05 23:04