1.请教一个简单问题,我现在用Serversocket和clientsocket做通讯,在Serversocket的ClientRead事件中用SendText(str)或者SendBuf发送数据,但是当字符串比较大的时候,超过了41k,在客户端无法收到完整的数据,没有结尾。在clientsocket的ClientSocketRead事件中用Socket.ReceiveText或者用Socket.ReceiveBuf都试过,都是无法收到完整的数据,如果不换控件,应该怎么处理呢?

解决方案 »

  1.   

    用流试试
    var
      SS: TStringStream;
      S: string;
    begin
      SS := TStringStream.Create(S);
      ClientSocket1.Socket.SendStream(SS);
    end;
      

  2.   

    怎么会收不到哪?socket 发送时不会一次到达, 像 tcp 这种协议一包数据在 1460 字节, 怎么会到 41k? 你看客户端这边把收下数据保存起来, 你一看大小就是 1460 了哈, 所以要 while 一下, 这里有点麻烦的是 while 用什么条件结束, 因为你8知要收的长度是多少, 因此就要有个数据结构定义在发送的内容前, 至少, 结构中要有一个将要发送的长度啦(用发接收方 while 结束), 这个结构长度又不能超过 1460 啦, 结构后面爱多长多长.
      

  3.   

    Server端Demo,其中ServerType = stNonBlocking,几百M的文件都能传输的
    -----------------------
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ScktComp, StdCtrls;type
      TForm1 = class(TForm)
        ServerSocket1: TServerSocket;
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure ServerSocket1ClientRead(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      g_SS: TFileStream;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
      g_SS := TFileStream.Create('C:\dest.bin', fmCreate);
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      g_SS.Free;
    end;procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      Buf: array [0..4095] of Byte;
      iRead: Integer;
    begin
      iRead := Socket.ReceiveBuf(Buf, SizeOf(Buf));
      g_SS.Position := g_SS.Size;
      g_SS.WriteBuffer(Buf, iRead);
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      ServerSocket1.Open;
    end;end.
      

  4.   

    if fsSend.Position < fsSend.Size - 1 then //还有数据没有发送。
          begin
            iLength := fsSend.Size - 1 - fsSend.Position;
            if iLength > iBYTEPERSEND then //将数据分段发送
              iLength := iBYTEPERSEND;
            GetMem(bufSend, iLength + 1);
            try
              fsSend.Read(bufSend^, iLength); //读取文件流数据
              Socket.SendBuf(bufSend^, iLength); //发送长度为iLength的数据
            finally
              FreeMem(bufSend, iLength + 1); //释放内存
            end;
      

  5.   

    分段发送,size标明字符串总长度,客户端接收累加content,直到size
    type
      custompack=record
        size:int64;
        content:string[255];
      end;
      

  6.   

    还是给你看一下短信协议包头的定义吧
          PSMGP_HEAD = ^TSMGP_HEAD;
          TSMGP_HEAD = PACKED RECORD
                total_length : longword;                     //消息总长度(含消息头和消息体)
                command_id : longword;                       //命令标识
                sequence_id : longword ;                     //消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)
          END;
          TSMGP_SPTOSMG_LOGIN = PACKED RECORD
                Head : TSMGP_HEAD;
                Body : TSMGP_LOGIN;
          END;
      

  7.   

    应该没有,用INDY不错,上百M都传了
      

  8.   

    我怎么这么反感INDY!!!!!!!!!!!!
      

  9.   

    这是由于Windows Socket底层的缓冲区不够造成的。SendText函数的返回值会告诉你具体有多少个字节的数据已经发送成功,你需要判断此返回值,如果未完全发送成功,则需要调用SendText将未发送的部分继续发送。SendBuf函数的返回值如果为-1则表示这次的发送是失败的,你需要重新发送整个数据包。