问题是在时间上发送超过2行

Lit*_*per 2 sockets delphi winsock delphi-7

我有套接字问题.
如果我发送超过两行文本TClientSocket然后服务器收到一行而不是两行.

客户部分:

ClientSocket1.Socket.SendText(Edit1.Text);//Text is 'Line1'
ClientSocket1.Socket.SendText(Edit2.Text);//Text is 'Line2'  
Run Code Online (Sandbox Code Playgroud)

服务器部分:

var
s: String;
begin
s := Socket.ReceiveText;
Memo1.Lines.Add(S);
Run Code Online (Sandbox Code Playgroud)

Memo1创建的行是'Line1Line2'
为什么?
对不起我的英语不好!

Ste*_*yne 5

SendText不发送CRLF.如果您需要发送新行,则必须明确地执行此操作:

ClientSocket1.Socket.SendText(Edit1.Text + #13#10);
ClientSocket1.Socket.SendText(Edit2.Text + #13#10);
Run Code Online (Sandbox Code Playgroud)

  • @Robrok:那就不要那样用:`var SL:TStringList; begin SL:= TStringList.create; 尝试SL.Text:= Socket.ReceiveText; 如果SL.Count> 1则开始Form.Left:= StrToInt(SL [0]); Form.Top:= StrToInt(SL [1]); 结束; 终于SL.Free; 结束;`应该为你做,你可以根据需要扩展它. (2认同)

Rem*_*eau 5

TClientSocketTServerSocket实现TCP / IP,它是没有消息边界概念的字节流(与UDP不同)。当您调用时SendText(),它只是将String内容按原样转储到套接字上。你打电话的时候ReceiveText(),它会返回当时套接字缓冲区中的当前内容。这就是为什么您看到服务器收到“ Line1Line2”的原因。如果要区分这两行,则需要在它们之间发送定界符(例如CRLF序列),然后需要更新服务器代码以查找该定界符。由于TCP / IP是字节流,因此在写入和读取之间没有保证的一对一关系。举个例子,您先写入5个字节,再写入5个字节,但是服务器一次接收了10个字节。因此,您的阅读代码需要对接收到的所有内容进行缓冲,然后可以在缓冲区中查找所需的数据,例如:

客户:

ClientSocket1.Socket.SendText(Edit1.Text + #13#10);
ClientSocket1.Socket.SendText(Edit2.Text + #13#10);
Run Code Online (Sandbox Code Playgroud)

服务器:

procedure TForm1.ServerSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Socket.Data := TMemoryStream.Create;
end;

procedure TForm1.ServerSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  TMemoryStream(Socket.Data).Free;
  Socket.Data := nil;
end;

procedure TForm1.ServerSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  Strm: TMemoryStream;
  RecvLen: Integer;
  StrmSize, I: Int64;
  Ptr: PByte;
  B: Byte;
  s: AnsiString;
begin
  Strm := TMemoryStream(Socket.Data);

  RecvLen := Socket.ReceiveLength;
  if RecvLen <= 0 then Exit;

  StrmSize := Strm.Size;
  Strm.Size := StrmSize + RecvLen;

  Ptr := PByte(Strm.Memory);
  Inc(Ptr, Strm.Position);

  RecvLen := Socket.ReceiveBuf(Ptr^, RecvLen);
  if RecvLen <= 0 then
  begin
    Strm.Size := StrmSize;
    Exit;
  end;

  Strm.Size := StrmSize + RecvLen;

  while (Strm.Size - Strm.Position) >= 2 do
  begin
    Strm.ReadBuffer(B, 1);
    if B <> 13 then Continue;

    Strm.ReadBuffer(B, 1);
    if B <> 10 then
    begin
      if B = 13 then
      begin
        Strm.Seek(-1, soCurrent);
        Continue;
      end;
    end;

    SetString(s, PAnsiChar(Strm.Memory), Strm.Position-2);

    StrmSize := Strm.Size - Strm.Position;
    if StrmSize then
    begin
      Strm.Clear;
    end else
    begin
      Ptr := PByte(Strm.Memory);
      Inc(Ptr, Strm.Position);
      Move(Ptr^, Strm.Memory^, StrmSize);
      Strm.Size := StrmSize;
      Strm.Position := 0;
    end;

    Memo1.Lines.Add(S);
  end;
 end;
Run Code Online (Sandbox Code Playgroud)