TWinSocketStream.WaitForData如何知道我是打算读还是写?

时间:2012-03-07 04:15:38

标签: delphi network-programming

我在阻塞模式下使用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一起使用的正确方法是什么?

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:5)

文档错误。 WaitForData()仅适用于阅读,而不适用于写作。

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

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

或者:

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