如何在 Delphi 中使用本机 WinSock api 制作简单的 send/receive 整数值?
How make a simply send/receive of integer value using native WinSock api in Delphi?
发送/接收整数值的正确方法是仅在一行中使用本机winsock,类似于下面的C++代码?我试过翻译这个,但不知道是否正确。有谁可以帮助我吗?
C++:
enum MyEnum { element01, element02 };
int width;
int SendInt(SOCKET sock, int i)
{
return Send(sock, (char *) &i, sizeof(i), 0);
}
if(SendInt(sock, MyEnum::element01) <= 0) return;
if(SendInt(sock, 0) <= 0) return;
if(recv(sock, (char *) &width, sizeof(width), 0) <= 0) return;
Delphi:
type
MyEnum = (element01, element02);
var
Width: Integer;
function SendInt(S: TSocket; I: Integer): Integer;
begin
Result := send(S, PAnsiChar(I)^, Length(IntToStr(I)), 0);
end;
if SendInt(Sock, Integer(MyEnum.element01)) <= 0 then Exit;
if SendInt(Sock, 0) <= 0 then Exit;
if recv(Sock, PAnsiChar(Width)^, Length(IntToStr(Width)), 0) <= 0 then Exit;
对send
的调用是错误的。您必须为要发送的字节和字节数提供一个无类型的缓冲区。这里绝对没有 IntToStr
的位置。
Result := send(S, I, SizeOf(I), 0);
对 recv
的调用也是如此。
if recv(Sock, Width, SizeOf(Width), 0) <= 0 then Exit;
使用Ord()
获取Delphi枚举类型的序数值是惯用的,所以Ord(MyEnum.element01)
而不是Integer(MyEnum.element01)
,但最终结果将是一模一样
您的代码不会在主机字节顺序和网络字节顺序之间进行转换。但是,C++ 代码也没有。
您使用:
function SendInt(S: TSocket; I: Integer): Integer;
begin
Result := send(S, PAnsiChar(I)^, Length(IntToStr(I)), 0);
end;
send()
的第二个参数是 无类型常量参数 ,这意味着您可以传递任何具有地址的内容,但将整数转换为一个指针然后取消引用它肯定是 不正确的 。
您可以简单地这样做:
begin
Result := send(S, I, SizeOf(I), 0);
end;
不过,您可能必须使用 htonl():
更改字节顺序
begin
// I := htonl(I); ??
Result := send(S, I, SizeOf(I), 0);
end;
您应该尝试这两种选择,看看结果如何。其中一个是正确的。
您还应该使用 recv() 以相同的方式传递整数。在 recv() 通话:
function RecvInt(S: TSocket; var J: Integer): Integer;
begin
Result := recv(S, J, SizeOf(J), 0);
// J := ntohl(J); ??
end;
发送/接收整数值的正确方法是仅在一行中使用本机winsock,类似于下面的C++代码?我试过翻译这个,但不知道是否正确。有谁可以帮助我吗?
C++:
enum MyEnum { element01, element02 };
int width;
int SendInt(SOCKET sock, int i)
{
return Send(sock, (char *) &i, sizeof(i), 0);
}
if(SendInt(sock, MyEnum::element01) <= 0) return;
if(SendInt(sock, 0) <= 0) return;
if(recv(sock, (char *) &width, sizeof(width), 0) <= 0) return;
Delphi:
type
MyEnum = (element01, element02);
var
Width: Integer;
function SendInt(S: TSocket; I: Integer): Integer;
begin
Result := send(S, PAnsiChar(I)^, Length(IntToStr(I)), 0);
end;
if SendInt(Sock, Integer(MyEnum.element01)) <= 0 then Exit;
if SendInt(Sock, 0) <= 0 then Exit;
if recv(Sock, PAnsiChar(Width)^, Length(IntToStr(Width)), 0) <= 0 then Exit;
对send
的调用是错误的。您必须为要发送的字节和字节数提供一个无类型的缓冲区。这里绝对没有 IntToStr
的位置。
Result := send(S, I, SizeOf(I), 0);
对 recv
的调用也是如此。
if recv(Sock, Width, SizeOf(Width), 0) <= 0 then Exit;
使用Ord()
获取Delphi枚举类型的序数值是惯用的,所以Ord(MyEnum.element01)
而不是Integer(MyEnum.element01)
,但最终结果将是一模一样
您的代码不会在主机字节顺序和网络字节顺序之间进行转换。但是,C++ 代码也没有。
您使用:
function SendInt(S: TSocket; I: Integer): Integer;
begin
Result := send(S, PAnsiChar(I)^, Length(IntToStr(I)), 0);
end;
send()
的第二个参数是 无类型常量参数 ,这意味着您可以传递任何具有地址的内容,但将整数转换为一个指针然后取消引用它肯定是 不正确的 。
您可以简单地这样做:
begin
Result := send(S, I, SizeOf(I), 0);
end;
不过,您可能必须使用 htonl():
更改字节顺序begin
// I := htonl(I); ??
Result := send(S, I, SizeOf(I), 0);
end;
您应该尝试这两种选择,看看结果如何。其中一个是正确的。
您还应该使用 recv() 以相同的方式传递整数。在 recv() 通话:
function RecvInt(S: TSocket; var J: Integer): Integer;
begin
Result := recv(S, J, SizeOf(J), 0);
// J := ntohl(J); ??
end;