Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 一次发送超过2行时出现问题_Delphi_Sockets_Delphi 7_Winsock - Fatal编程技术网

Delphi 一次发送超过2行时出现问题

Delphi 一次发送超过2行时出现问题,delphi,sockets,delphi-7,winsock,Delphi,Sockets,Delphi 7,Winsock,我的插座有问题。 若我使用发送两行以上的文本,服务器会收到一行而不是两行 客户部分: ClientSocket1.Socket.SendText(Edit1.Text);//Text is 'Line1' ClientSocket1.Socket.SendText(Edit2.Text);//Text is 'Line2' 服务器部件: var s: String; begin s := Socket.ReceiveText; Memo1.Lines.Add(S); 备忘录1创建的行是“

我的插座有问题。
若我使用发送两行以上的文本,服务器会收到一行而不是两行

客户部分:

ClientSocket1.Socket.SendText(Edit1.Text);//Text is 'Line1'
ClientSocket1.Socket.SendText(Edit2.Text);//Text is 'Line2'  
服务器部件:

var
s: String;
begin
s := Socket.ReceiveText;
Memo1.Lines.Add(S);
备忘录1创建的行是“Line1Line2”
为什么?

对不起我的英语

您需要向Edit1添加CRLF或换行符。文本和Edit2。文本不发送CRLF。如果需要发送新行,则必须明确:

ClientSocket1.Socket.SendText(Edit1.Text + #13#10);
ClientSocket1.Socket.SendText(Edit2.Text + #13#10);

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

客户:

ClientSocket1.Socket.SendText(Edit1.Text + #13#10);
ClientSocket1.Socket.SendText(Edit2.Text + #13#10);
服务器:

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;
过程TForm1.ServerSocket1Connect(发送方:TObject;套接字:TCustomWinSocket);
开始
Socket.Data:=TMemoryStream.Create;
结束;
过程TForm1.ServerSocket1Disconnect(发送方:TObject;套接字:TCustomWinSocket);
开始
TMemoryStream(Socket.Data).Free;
Socket.Data:=nil;
结束;
过程TForm1.ServerSocket1Read(发送方:TObject;套接字:TCustomWinSocket);
变量
Strm:TMemoryStream;
RecvLen:整数;
StrmSize,I:Int64;
Ptr:PByte;
B:字节;
s:翻译;
开始
Strm:=TMemoryStream(Socket.Data);
RecvLen:=插座。接收长度;

如果RecvLen,我不熟悉Delphi的SendText方法,但我看不到任何地方在文本中指定回车。服务器接收一行而不是两行。但是如果我使用:if Command='FormX',则开始Form.Left:=stroint(Socket.ReceiveText)@罗布罗克:那就不要这样使用:
var-SL:TStringList;begin SL:=TStringList.create;try SL.Text:=Socket.ReceiveText;如果SL.Count>1,则开始Form.Left:=stroint(SL[0]);Form.Top:=stroint(SL[1]);结束;最后,自由;结束应该为您完成,您可以根据需要扩展它;Mess:=Socket.ReceiveText;绑定:=副本(1,4);如果Bind='LEFT',则开始FrmLeft:=复制(Mess,5,3);表1.左:=stroint(FrmLeft);结束--简单的