我找到了一个函数来测试远程PC上是否打开了特定的tcp端口。它似乎工作正常,但是当我为变量client.sin_addr.S_addr
指定一个值时,其他值似乎被分配了乱码值,至少我没有期望看到像我看到的那样的值。 / p>
分配client.sin_addr.S_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))
分配client.sin_addr.S_addr
后的客户记录值:
(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;
答案 0 :(得分:3)
这些字段被声明为保持Char
值,因此调试器会以这种方式解释它们并尝试显示字符。当然,它们并不是真正的字符,但是调试器并不知道更好。
十进制值1745529024是十六进制0x680AA8C0。最重要的字节是0x68,当解释为ASCII字符时,它是小写的 h 。值0x0A是换行符,表示为Delphi字符文字#10
。等等。
答案 1 :(得分:1)
这是一个变体记录,就像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
。
总之,情况正常,无需担心。