我正在尝试重现"针对Delphi的netstat并遇到了一些问题:
到目前为止,这是我的代码:
program NetstatExample;
{$APPTYPE CONSOLE}
uses
Windows,
Winsock2;
const
TCP_TABLE_OWNER_PID_ALL = 5;
ANY_SIZE = 1;
type
TCP_TABLE_CLASS = Integer;
in6_addr = record
case Integer of
0: (Byte: array [0..15] of u_char);
1: (Word: array[0..7] of u_short);
2: (s6_bytes: array [0..15] of u_char);
3: (s6_addr: array [0..15] of u_char);
4: (s6_words: array[0..7] of u_short);
end;
TIn6Addr = in6_addr;
PIn6Addr = ^in6_addr;
PTMib_TCP6Row = ^TMib_TCP6Row;
TMib_TCP6Row = packed record
LocalAddr : IN6_ADDR ;
dwLocalScopeId : DWORD ;
dwLocalPort : DWORD ;
RemoteAddr : IN6_ADDR ;
dwRemoteScopeId : DWORD ;
dwRemotePort : DWORD ;
dwState : DWORD ;
dwProcessId : DWORD ;
end;
PTMIB_TCP6TABLE = ^TMIB_TCP6TABLE;
TMIB_TCP6TABLE = record
dwNumEntries : DWORD;
Table: array[0..ANY_SIZE - 1] of TMib_TCP6Row;
end;
var
GetExtendedTcpTable : function (pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL; lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWord; stdcall;
iphHandle : HMODULE;
TableSize : DWORD;
TCPTable : PTMIB_TCP6TABLE;
I : Integer;
begin
try
iphHandle := LoadLibrary('iphlpapi.dll');
if iphHandle = 0 then Exit;
GetExtendedTcpTable := GetProcAddress(iphHandle, 'GetExtendedTcpTable');
if @GetExtendedTcpTable = NIL then Exit;
if GetExtendedTcpTable(nil, @TableSize, False, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0) <> ERROR_INSUFFICIENT_BUFFER then Exit;
GetMem(TCPTable, TableSize);
try
if GetExtendedTcpTable(TCPTable, @TableSize, False, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0) <> NO_ERROR then Exit;
for I := 0 to TCPTable^.dwNumEntries - 1 do
begin
// Detect AF_INET6 and/or AF_INET4 family
// Display Remote Address in proper format for each family - XP compatible?!
end;
finally
FreeMem(TCPTable, TableSize);
end;
finally
readln;
end;
end.
在这里,我使用AF_INET6,所以我也可以获得ipv6连接。
问题是:
答案 0 :(得分:2)
Q1:您的GetExtendedTcpTable
调用返回指定地址系列中的地址,即。如果你传递它AF_INET6
它只返回IPv6地址,如果你传递它AF_INET
它只返回IPv4地址。所以没有必要区分,你只需将返回的表转换为正确的表类型,如文档的备注部分所述(上面链接)。
Q2:这是我的实施(我希望它是正确的):
function AddrStr(Addr: Cardinal): string;
var
P: PAnsiChar;
begin
P := inet_ntoa(PInAddr(@Addr)^);
SetString(Result, P, StrLen(P));
end;
function Addr6Str(const Addr: IN6_ADDR): string;
var
I: Integer;
begin
Result := '';
for I := 0 to 7 do
begin
if Result <> '' then
Result := Result + ':';
Result := Result + LowerCase(IntToHex(ntohs(Addr.Word[I]), 1));
end;
Result := '[' + Result + ']';
end;
...或者查看Free Pascal的套接字单元,NetAddrToStr
和NetAddrToStr6
。