简单代码示意如下:
  
  如果用
  sResponse := IdTCPClient1.ReadLn;
  则数据读不全,读出的数据是
  #1#4#0#1#0#1#0'@j4譎'#8'傆O '#$A8
  
  如果用
  setlength(sResponse,64);
  IdTCPClient1.ReadBuffer(sResponse[1],64);
  则可以读全,但是这里是写死了读取64个字节,怎么样才能读全部服务端返回的数据呢?
全部数据是:#1#4#0#1#0#1#0'@j4譎'#8'傆O ?'#$A'僑漃'#$10'??S?\{?'#$11'技縗{?'#$11'技縗{?'#$11'技烤>eQ陣?'注:此是客户端代码,服务端是由VC编写的
    

解决方案 »

  1.   

    先取得缓冲里数据的个数,然后再ReadBuffer
    RecvCount:=self.IdTCPClient.IOHandler.InputBuffer.Size;
      

  2.   

    回2楼: 服务器端没有约定数据包大小,因为大小不固定,也没有约定数据包结尾的标志,这里只是想用IdTCPClient一次读出全部服务端返回的数据回3楼:IdTCPClient.IOHandler.InputBuffer.Size好像不对呀,IOHandler没有InputBuffer属性啊,如果改成IdTCPClient.InputBuffer.Size,则值是0,我的开发环境是delphi7。
      

  3.   

    通常情况下都是先用ReadBuffer收一个固定长度的报文头, 报文头里说明还剩下多少字节,然后继续收就可以了。你这种情况只能在一个线程里轮询InputBuffer.Size,如果不为0,就用ReadBuffer收数据即可。
      

  4.   

    回5楼:必须要另开一个线程收数据吗?
    这样写可以吗?
    IdTCPClient1.WriteBuffer(str[1],Length(str));
    setlength(sResponse,64); 
    IdTCPClient1.ReadBuffer(sResponse[1],64); 以上代码是服务端返回字节是64的时候是可以正常工作的,但是需要写死读取的字节数。如果用线程轮寻的话,可否提供一下示例代码,谢谢
      

  5.   

    最好修改一下通讯协议,先发送一个4字节的数据长度
    i1:integer;IdTCPClient1.WriteBuffer(str[1],Length(str));i1:=IdTCPClient1.ReadInteger();setlength(sResponse,i1); 
    IdTCPClient1.ReadBuffer(sResponse[1],i1);  线程轮询代码,只是用来说明问题,很多细节没有处理,用的是indy10
    procedure nthread.Execute;
    var
        RecvCount : integer;
    begin
    while (True) do
      begin
        if self.Terminated then exit;
        Sleep(1);
        try
            try
                  //是否有数据,非阻塞式
                   RecvCount:=self.IdTCPClient.IOHandler.InputBuffer.Size;
                   if (RecvCount>0) then
                      begin
                        //有数据
                         //从网络接收数据
                          with self.IdTCPClient.IOHandler.InputBuffer do
                          begin
                                ExtractToBytes(RecvBuffer,RecvCount,false);
                          end;
                          //清除缓冲
                          self.IdTCPClient.IOHandler.InputBuffer.Clear;
                      end;
            except
                //错误,跳过发送
                Continue;
            end;
    end;
      

  6.   

    首先谢谢空白的历史1966至1976的热心帮助!通讯协议是不可能改了,因为服务端不是由我开发
    后来我是这样写的,暂时工作正常,不知道会不会有问题,
    IdTCPClient1.WriteBuffer(str[1],Length(str)); 
    IdTCPClient1.ReadFromStack;//加上这句后,下面的IdTCPClient1.InputBuffer.Size才会有值,否则是0,我用的是indy 9,如果是indy10的话不知道是不是就不需要这句了呢
    i1 := IdTCPClient1.InputBuffer.Size;
    IdTCPClient1.ReadBuffer(sResponse[1],i1);
      

  7.   

    客户端的接收数据工作本身就要放在线程里面(因为服务器可能不止发一次)
    用ReadBuffer就可以实现
      

  8.   

    不要使用readln,实际上这是一个以换行符分割的一个简单文本传输协议。建议使用write(TStream,...)并且最后的参数指定需要发送size,接收端也一样,使用stream接收,并且接收size,这样子对于其他开发工具开发的程序也比较方便,就是对于小数据,最前面就是一个4字节,表示后续实际内容的长度,按规则接收即可。
      

  9.   

     
    接受端sResponse := IdTCPClient1.ReadLn(enUTF8); 
      

  10.   

     
    接受端sResponse := IdTCPClient1.ReadLn(enUTF8);