一台公网服务器中转两台不同内网电脑的TCP文件传输,公网服务器用:ServerSocket1  模式:stNonBlocking   
内网电脑用ClientSocket1  模式也是:ctNonBlocking
部分源码://全局变量设置:
var
Sok2:TCustomWinSocket;
MyBuffer: array[0..99999] of byte; {设置接收缓冲区}//公网服务器收到客户端连接的时候,建立socket套接字
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
beginSok2:=Socket;end;
//公网服务器接收的时候,立即进行转发
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  len, t: Integer;
begin  t := Socket.ReceiveLength;
  len := Socket.ReceiveBuf(MyBuffer, t);
  Sok2.SendBuf(MyBuffer, len);  //出错的地方,转发不完整,掉包。 
  //注明:我把上面这句话放到线程里面处理,转发也同样不完整,掉包。
end;
问题在公网服务器接收立即进行转发,因为TCP会把一个整大包分成很多小包进行传输,第一个小包可以顺利转发,第二个,第三个,后面的小包,就不行了,发不出去,我用了线程处理,也发不了去。各位高手一定明白其中的道理,就是接收太快了,发送太慢了,请问一般是用什么办法来进行顺利转发的?

解决方案 »

  1.   

    一次收到t个字节,也分多次发走,每次发m个字节,直到发完t个字节
      

  2.   

    大概的思路我也懂,就是不会写过程,关键是一边接收,一边发送,这个过程怎么写,发送的代码,是直接写在接收里面,还是用另外开线程,如果另外用线程发送,会不会与接收的内存块冲突?我试过用线程发送,TCP分包的顺序会乱掉。谁有成熟的代码?中转服务器接收后,然后如何触发发送过程,是在接收的函数里完成发送过程,还是另开线程完成,如果另开线程完成发送过程,那线程单元中,如何调用Form1主单元的“接收到的内存块MyBuffer”?
      

  3.   

    可以这样,先读取Buf到写到Stream中,等接收完成再转发。while Socket.ReceiveBuf(Buf, SizeOf(Buf)) > 0 do
    begin
      Stream.WriteBuffer(buf, SizeOf(Buf));
    end;Sok2.SendStream(Stream, Stream.Size);