第一次使用TTcpServer和TTcpClient这两个组件,出现了很奇怪的问题。
首先TTcpClient的BlockMode属性为bmBlocking.与TTcpClient建立连接后用Sendln()方法发送数据。如
TcpClient1.Sendln('1');TTcpServer端的BlockMode属性为bmThreadBlocking.它的OnAccpet方法如下:
procedure TForm1.Server1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
  textAll,text: String;
begin
  text := ClientSocket.Receiveln ;
  while Trim(text)<>''do
  begin
    textAll := textAll + Trim(text);
    text := ClientSocket.Receiveln;
  end;
  if Trim(textAll)<>'' then
  begin
    if Length(Trim(textAll))>1 then
      Application.MessageBox('不能一次发送多条指令','提示',MB_OK)
    else
      case StrToInt(textAll) of
         1: CloseSystem;
                else
           ShowMessage('异常');
      end;
  end;
end;CloseSystem是我自定义的一个关机的方法。现在出现的问题为:
客户端与服务器能成功连接,在客户端用Sendln()方法发送数据'1'后,服务器端却没有响应。但是若此时先关闭客户端,不关闭服务器端,服务器端即会执行该关机的方法自动关机。
为什么我关闭客户端后服务器端才能执行相应的方法呢?

解决方案 »

  1.   

    ClientSocket.receiveLn函数
    遇到回车才能返回的,或者有足够多的数据才能返回,否则,一直阻塞状态。所以你发送数据'1'后,text:=ClientSocket.Receiveln ; 已经读出
    while trim(text)<>'' do
    begin
       ...
       text:=ClientSocket.ReceiveLn;///会一直阻塞在这里直到客户端关闭
    end;客户端关闭后就执行了下面的代码,然后关机。
      

  2.   

    谢谢楼上指点?那请问除了ReceiveLn之外有没有其他好一点的方法?
      

  3.   

    能不能给个详细一点的代码啊呵呵~~~我不太会用SendBuf方法
      

  4.   

    你运气好呀,我也在写这个方面的程序
    服务器端程序:procedure TfrmMain.TcpServerAccept(Sender: TObject;
      ClientSocket: TCustomIpClient);
    const
      BUFFER_SIZE = 255;
    var
      S: string;
      Buffer: array[0..BUFFER_SIZE - 1] of Char;
      i: Integer;
      Mem: TMemoryStream;
    begin
      Mem := TMemoryStream.Create;
      try
        repeat
          i := ClientSocket.ReceiveBuf(Buffer, BUFFER_SIZE);
          Mem.Write(Buffer, i);
        until i < BUFFER_SIZE;
        SetLength(S, Mem.Size);
        if Length(S) > 0 then
        begin
          Move(Mem.Memory^, S[1], Length(S));
          ShowMessageFmt('IP=%s; Content=%s', [ClientSocket.LocalHostAddr, S]);
        end;
      finally
        Mem.Free;
      end;
    end;
    客户端procedure TForm1.Button1Click(Sender: TObject);
    var
      S: String;
    begin
      S := 'procedure TForm1.Button1Click(Sender: TObject);';
      TcpClient.SendBuf(S[1], Length(S));
    end;
      

  5.   

    http://topic.csdn.net/u/20080507/11/7adf3e3b-16b9-4c11-a01b-83be267b7c92.html
    我遇到过同样的问题,这个也许可以帮你
      

  6.   

    procedure TForm1.Server1Accept(Sender: TObject; 
      ClientSocket: TCustomIpClient); 
    var 
      textAll,text: String; 
    begin 
      text := ClientSocket.Receiveln ; 
      while Trim(text) <>''do 
      begin 
        if Trim(text) <>'' then 
        begin 
          if Length(Trim(text))>1 then 
            //Application.MessageBox('不能一次发送多条指令','提示',MB_OK)//这里不能使用MessageBox,因为这是在子线程当中执行的 
          else 
            case StrToInt(text) of 
              1: CloseSystem; 
              else 
               //ShowMessage('异常'); //子线程也不能使用ShowMessage
            end; 
        end;  
        text := ClientSocket.Receiveln; 
      end; end; 
      

  7.   

    StrToInt(text)  最好改为 StrToIntDef(text,-1)或者StrToIntDef(text,0)等,否则如果发送了非数字符就会出异常