Delphi winsock为什么值中的sockaddr_得到;乱码;分配InAddr.S_地址时

Delphi winsock为什么值中的sockaddr_得到;乱码;分配InAddr.S_地址时,delphi,winsock,Delphi,Winsock,我找到了一个函数来测试远程PC上是否打开了特定的tcp端口。它似乎工作正常,但当我为变量client.sin\u addr.S\u addr赋值时,其他值似乎被分配了乱码值,至少我没想到会看到像我看到的那样的值 在分配客户端.sin\u addr.S\u addr之前,客户端记录值: (2, 39173, ((#0, #0, #0, #0), (0, 0), 0), (#0, #0, #0, #0, #0, #0, #0, #0), 2, (#5, '™', #0, #0, #0, #0, #0

我找到了一个函数来测试远程PC上是否打开了特定的tcp端口。它似乎工作正常,但当我为变量
client.sin\u addr.S\u addr
赋值时,其他值似乎被分配了乱码值,至少我没想到会看到像我看到的那样的值

在分配
客户端.sin\u addr.S\u addr
之前,客户端记录值:

(2, 39173, ((#0, #0, #0, #0), (0, 0), 0), (#0, #0, #0, #0, #0, #0, #0, #0), 2, (#5, '™', #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0))
(2, 39173, (('À', '¨', #10, 'h'), (43200, 26634), 1745529024), (#0, #0, #0, #0, #0, #0, #0, #0), 2, (#5, '™', 'À', '¨', #10, 'h', #0, #0, #0, #0, #0, #0, #0, #0))
分配
Client.sin\u addr.S\u addr
后的客户端记录值:

(2, 39173, ((#0, #0, #0, #0), (0, 0), 0), (#0, #0, #0, #0, #0, #0, #0, #0), 2, (#5, '™', #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0))
(2, 39173, (('À', '¨', #10, 'h'), (43200, 26634), 1745529024), (#0, #0, #0, #0, #0, #0, #0, #0), 2, (#5, '™', 'À', '¨', #10, 'h', #0, #0, #0, #0, #0, #0, #0, #0))
请注意,
1745529024
是IP地址的正确表示形式
192.168.10.104

据我所知,该函数的工作原理与预期一致。我只是不喜欢那些乱七八糟的值

这是正常的,我应该担心,还是忽略它

function PortTCP_IsOpen(dwPort : Word; InetAddress : AnsiString) : boolean;
var
  client : sockaddr_in;
  sock   : Integer;

  GInitData: TWSAData;
  ret : Integer;
  res : integer;
  msg : string;
begin
  Result:=False;
  ZeroMemory(@client, SizeOf(client));

  ret := WSAStartup($0002, GInitData); //initiates use of the Winsock DLL
  if ret <> 0 then RaiseLastOSError;
  try
    client.sin_family      := AF_INET;  //Set the protocol to use , in this case (IPv4)
    client.sin_port        := htons(dwPort); //convert to TCP/IP network byte order (big-endian)
    // before value
    client.sin_addr.S_addr := inet_addr(PAnsiChar('192.168.10.104'));     //inet_addr(PAnsiChar(ansistring(GetIPFromHost(InetAddress))));  //convert to IN_ADDR  structure
    // after value
    sock  := socket(AF_INET, SOCK_STREAM, 0);    //creates a socket
    Result:= connect(sock, client, SizeOf(client)) = 0;  //establishes a connection to a specified socket
    if Result then
    begin
      if not closesocket(sock) = 0 then
      begin
        res := WSAGetLastError;
        msg := SysErrorMessage(res);
        raise Exception.CreateFmt('%s Code:%d',[msg, res]);
      end;
    end else
    begin
      res := WSAGetLastError;
      msg := SysErrorMessage(res);
      raise Exception.CreateFmt('%s Code:%d',[msg, res]);
    end;
  finally
    WSACleanup;
  end;
end;
函数PortTCP_IsOpen(dwPort:Word;InetAddress:ansisting):布尔值;
变量
客户:sockaddr_in;
sock:整数;
GInitData:TWSAData;
ret:整数;
res:整数;
msg:string;
开始
结果:=假;
零内存(@client,SizeOf(client));
ret:=WSAStartup($0002,GInitData)//启动Winsock DLL的使用
如果ret为0,则RAISELASTERROR;
尝试
client.sinu family:=AF\u INET//设置要使用的协议(在本例中为IPv4)
client.sinu端口:=htons(dwPort)//转换为TCP/IP网络字节顺序(大端)
//价值之前
client.sin_addr.S_addr:=inet_addr(PAnsiChar('192.168.10.104'))//inet_addr(PAnsiChar(ansistring(GetIPFromHost(InetAddress)))//转换为IN_ADDR结构
//后值
sock:=套接字(AF\u INET,sock\u STREAM,0)//创建套接字
结果:=connect(sock,client,SizeOf(client))=0//建立到指定套接字的连接
如果结果是这样的话
开始
如果未闭合插座(sock)=0,则
开始
res:=WSAGetLastError;
消息:=系统错误消息(res);
引发异常。CreateFmt('%s代码:%d',[msg,res]);
结束;
结束其他
开始
res:=WSAGetLastError;
消息:=系统错误消息(res);
引发异常。CreateFmt('%s代码:%d',[msg,res]);
结束;
最后
WSACleanup;
结束;
结束;

这些字段被声明为包含
Char
值,因此调试器将以这种方式解释它们并尝试显示字符。当然,它们不是真正的字符,但是调试器不知道什么更好


十进制值1745529024为十六进制0x680AA8C0。最高有效字节为0x68,当解释为ASCII字符时,该字节为小写h。值0x0A是换行符,表示为Delphi字符文本,如
#10
。以此类推。

这是一个变体记录,就像C联合一样。这是:

type
  in_addr = record
    case integer of
      0: (S_un_b: SunB);
      1: (S_un_w: SunW);
      2: (S_addr: u_long);
  end;
因此,
S_addr
保存值
1745529024
,其他两个成员覆盖在同一内存上。在十六进制中,
1745529024
$680AA8C0

现在,什么是SunB

type
  SunB = record
    s_b1, s_b2, s_b3, s_b4: u_char;
  end;
因此,调试器将
S_addr
的四个字节解释为ANSI编码字符,因此您可以在调试器中看到这些字符。在本地ANSI表中查找
$68
$0A
$A8
$C0
,您将找到调试器显示给您的四个值

同样,对于
SunW
,它是:

type
  SunW = record
    s_w1, s_w2: u_short;
  end;
而构成$680AA8C0的两个单词实际上是
$A8C0=43200
$680A=26634


总之,情况正常,没什么可担心的。

谢谢Rob,非常有帮助谢谢你们两个-当然现在一切都很有意义,对C union不太熟悉,特别是内存空间不是共享的。