recv函数不接收所有字节

时间:2016-02-21 04:57:27

标签: sockets delphi

我正在使用delphi(RAD Studio 10)制作一个小应用程序客户端和服务器。服务器只发送文本。

下一个函数正确返回发送的字节数。例如,我发送'hello'(客户端):

procedure TTCPConnection.Write(S: String);
var buff : string;
begin
  buff = S+EOL;
  WriteBuffer(buff, Length(buff));
end;

其中:S = 'hello'EOL = #13#10buff = 'hello'+EOL

procedure TTCPConnection.WriteBuffer(var Buffer; const Len: Cardinal);
var
  a : Int16;
begin
  a :=  send(FSocket, Buffer, Len, 0);
  if (a = SOCKET_ERROR) and FConnected then
  begin
    HandleError;
    Disconnect;
  end;
end;

在上一个函数中:send(FSocket, Buffer, Len, 0)返回7,发送的字节数('hello + EOL')。

服务器端:

function TTCPConnection.ReadLn(Delim: String = EOL): String;
const BUFFER_SIZE = 255;
var
  Buff, Buf: string;
  I, L: Cardinal;
begin
  Result := '';
  I := 1;
  L := 1;
  SetLength(Buff, BUFFER_SIZE);
  Buf := AnsiString(Buff);
  while Connected and (L <= Cardinal(Length(Delim))) do
  begin
    if recv(FSocket, Buffer, Len, 0) < 1 then exit;
    Buf := Buff[I];
    if Buff[I] = Delim[L] then
      ...
    ...
end;

(在前面的代码中,我只包含Buf var,仅用于调试目的)。当我调试获得这个结果时:

Buff = {'h', #0, 'e', #0, 'l', #0, 'l'}(7个字节),下一次执行此行recv(FSocket, Buffer, Len, 0)时,程序什么也不做,我想这是因为recv函数没有任何东西可以接收(发送了7个字节)。

我需要帮助才能正确接收所有字节。我不知道为什么他们按顺序排列(h-#0-e-#0-l-#0-l)。

1 个答案:

答案 0 :(得分:0)

从RAD Studio 2009开始,stringWideChar个字符组成。 CharWideChar的别名,为16位。 Length()函数返回字符数,而不是字节数。

您可能需要考虑使用TEncoding将字符串转换为TBytesarray of byte)进行发送,反之亦然。我不知道你的TTCPConnection课程,所以可能需要调整代码,但是这里使用TEncoding.UTF8发送部分:

procedure TTCPConnection.Write(S: String);
var buff : TBytes;
begin
  buff := TEncoding.UTF8.GetBytes(S+EOL);  // Convert to bytes using UTF8 encoding
  WriteBuffer(buff, Length(buff));
end;

这是我在XE5中测试项目的接收器代码,其中我使用了TTcpServer组件

procedure TForm3.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
  a: array[0..255] of byte;
  b: TBytes;
  i, n: integer;
  s: string;
begin
  n := ClientSocket.ReceiveBuf(a,255,0);
  SetLength(b, n);
  for i := Low(b) to High(b) do b[i] := a[i]; // copy from the receive buffer
  s := TEncoding.UTF8.GetString(b);           // convert UTF8 bytes to string
  Memo1.Lines.Add(format('%4d %s',[n,s]));
end;

最后一些有用的文档链接:

TEncoding

UTF-8 Conversion Routines