我正在使用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#10
,buff = '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
)。
答案 0 :(得分:0)
从RAD Studio 2009开始,string
由WideChar
个字符组成。 Char
是WideChar
的别名,为16位。 Length()
函数返回字符数,而不是字节数。
您可能需要考虑使用TEncoding
将字符串转换为TBytes
(array 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;
最后一些有用的文档链接: