最近参考了bdmh朋友
http://hi.baidu.com/jasonggg/blog/item/6de82a86f30a3d3967096e21.html
关于ICS传送数据的例子。//服务器端:
procedure TForm1.ClientDataAvailable(Sender: TObject; Error: Word);
var
  S: String;
begin
   with Sender as TTcpSrvClient do
   begin
     S := ReceiveStr;
     if SameText(S,'File') then
     begin
       SendStr('Size');
       S := ReceiveStr;
       if StrToInt64(S) > 0 then
       begin
         .....
       end;
     end;       
   end;
end;//客户端
procedure TForm1.SendInfo;
begin
  WSocket1.SendStr('File');
end;procedure TForm1.WSocket1DataAvailable(Sender: TObject; ErrCode: Word);
var
  S: String;
  AStream: TMemoryStream;
  Size: Int64;
begin
  AStream := TMemoryStream.Create;
  try
    AStream.LoadFromFile('d:\....');
    AStream.Position := 0;
    S := WSocket1.ReceiveStr;
    Size := AStream.Size;
    WSocket1.SendStr(IntToStr(Size));
    .....
  finally
    FreeAndNil(AStream);
  end;
end;不知道为什么不能交互呢?
以前没有用过ICS,还请勿怪!
对了还要请问下文件传送是怎么做的呢?非常感激朋友们了!

解决方案 »

  1.   

    基于异步消息模式的,一般只调用一次ReceiveStr,并且需要进行消息(报文)边界检查,然后对粘包部分进行切分。
      

  2.   

    unsigned: 非常感谢你的好几次答复!           还请问下:能否先调用ReceiveStr,分解验证正确后调用Receive传文件呢?
      

  3.   

    ReceiveStr是按String接收,可以开一个缓冲,比如为TTcpSrvClient定义一个成员BufferedData: AnsiString,然后每次接收到的数据都往后叠加类似于
    BufferedData := BufferedData + ReceiveStr;
    然后每次都只在BufferedData当中判断,只在判断准确了,然后就把取到的部分删除
    MyPacketData := Copy(BufferedData, 1, PacketLength);
    Delete(BufferedData, 1, PacketLength);
      

  4.   

    你的意思是不是传文件也是用ReceiveStr函数而不用Receive(Buffer : TWSocketData; BufferSize: Integer)函数?举例:A->B 传文件
    A: SendStr('Start');
        SendStr(需要传的文件第一行)
        SendStr(需要传的文件第二行)
        ......
        SendStr(需要传的文件最后一行)
        B:  BufferedData := BufferedData + ReceiveStr;
        
        最后MyPacketData := Copy(BufferedData, 1, PacketLength); 
        if MyPacketData = 'Start' then
        begin
          Delete(BufferedData, 1, PacketLength); 
        end;    此时BufferedData就是文件内容不知道我的理解对不对?
      

  5.   

    还是再麻烦僵哥一下:如果用Receive(Buffer : TWSocketData; BufferSize: Integer)函数来传递图片,
    这时如何获取BufferSize呢?这个BufferSize得事先定义一个最大值?
      

  6.   

    僵哥:在ICS中就不能这样?
    先SendStr(BufferSize)  ->  ReceiveStr(BufferSize)然后再Send(Buffer,Buffersize)  -> ReceiveStr(Buffer,BufferSize)吗?这样ICS用起来还真有点不方便。谢谢你这么多次帮助!
      

  7.   

    TCP是流协议,不可能一次Receive就能够或者只是对端一次Send过来的东西。有可能对端一次Send出来的是:aaabbbccc
    而一次receive到的只有aaab后面的bbccc需要下一次Receive.或者有可能对端先Send出来的是aaa,接着send出来的是bbb再接着send出来的是ccc
    而你可能第一次收到的是aaab第二次收到的是bbccc
      

  8.   

    理解了。
    看来我得好看看同步与异步之间的差异。
    顺便提一下Indy,它能完全做到我所说的方式交互,是不是就是同步模式下的好处呢?
      

  9.   

    只要是TCP协议都会存在同样的问题。
      

  10.   

    在TCP当中进行交互,如果有“报文”概念的,首先需要的就是定义报文的边界,比如Indy当中的WriteLN/ReadLN,实际上就把换行符(在Windows下是#13#10,其它平台是#10)作为一个报文边界,当然这只能对于文本协议有效,HTTP、FTP等也是如此。