이것은 winsocks2 및 유니 코드 지원을 사용하여 XE3-XE7에서 IP 주소를 확인하는 데 사용하는 방법에 대한 예입니다.
소켓 지원은 모든 호출에서 초기화되고 초기화되지 않으므로 성능이 떨어지지 만 리팩토링은 쉽지 않습니다.
또한 유지 관리가 용이하도록 목적에 맞게 최적화되지 않았습니다.
uses
Winapi.Winsock2;
type
PAddrInfo = ^TAddrInfo;
TAddrInfo = packed record
ai_flags: integer;
ai_family: integer;
ai_socktype: integer;
ai_protocol: integer;
ai_addrlen: NativeInt;
ai_canonname: PCHAR;
ai_addr: PSOCKADDR;
ai_next: PAddrInfo;
end;
function GetAddrInfo(const nodeName: PCHAR; const serviceName : PChar; const hints: PAddrInfo; var result: PAddrInfo): integer; stdcall; external 'ws2_32.dll' name 'GetAddrInfoW';
procedure FreeAddrInfo(const addrInfo: PAddrInfo); stdcall; external 'ws2_32.dll' name 'FreeAddrInfoW';
function ResolveIpAddress(const hostName: string; const ipv6: boolean): string;
const
BUFFER_SIZE = 32768;
var
data: TWSAData;
error: integer;
requestError: integer;
r: PAddrInfo;
s: string;
hints: TAddrInfo;
buffer: TArray<byte>;
length: DWORD;
begin
error:= WSAStartup(MAKEWORD(2, 2), data);
try
if (error = 0) then
begin
r:= nil;
try
ZeroMemory(@hints, sizeof(TAddrInfo));
if (ipv6) then
hints.ai_family:= AF_INET6
else
hints.ai_family:= AF_INET;
requestError:= GetAddrInfo(PCHAR(hostName), nil, @hints, r);
if (requestError = 0) then
begin
length:= BUFFER_SIZE;
SetLength(buffer, BUFFER_SIZE);
if (WSAAddressToString(r.ai_addr^, r.ai_addrlen, nil, @buffer[0], length) = 0) then
begin
setLength(buffer, length * 2);
s:= TUnicodeEncoding.Unicode.GetString(@buffer[0]);
exit(s);
end
else
exit('0.0.0.0');
end
else
exit('0.0.0.0');
finally
FreeAddrInfo(r);
end;
end
finally
if (error = 0) then
WSACleanup();
end;
end;
'R'의 다른 매개 변수를 확인 했습니까? 그들은 무효로합니까? – mg30rg
'HostName' 매개 변수 유형을'AnsiString'으로 변경하십시오. – TLama
@tlama 그것이 효과가있다! 그게 무슨 상관이야!? – PSyLoCKe