插座有问题
如果我使用TClientSocket
发送超过两行文本,则服务器会收到一行而不是两行。
客户端部分:
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);
Memo1创建的行是'Line1Line2'
为什么呢?
对不起我的英文!
答案 0 :(得分:5)
SendText
不会发送CRLF。如果您需要发送新行,则必须明确地执行此操作:
ClientSocket1.Socket.SendText(Edit1.Text + #13#10);
ClientSocket1.Socket.SendText(Edit2.Text + #13#10);
答案 1 :(得分:4)
TClientSocket
和TServerSocket
实现TCP / IP,这是一个没有消息边界概念的字节流(与UDP不同)。当您调用SendText()
时,它只是将字符串内容按原样转储到套接字上。当你调用ReceiveText()
时,它会返回当时套接字缓冲区中当前的内容。这就是为什么你看到服务器收到'Line1Line2'。如果要区分这两行,则需要在它们之间发送分隔符,例如CRLF序列,然后需要更新服务器代码以查找它。由于TCP / IP是字节流,因此写入和读取之间不保证一对一的关系。例如,你写了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;
答案 2 :(得分:1)
您需要在Edit1.Text和Edit2.Text
中添加CRLF或换行符