Wininet 客户端端口 - delphi 2010
Posted
技术标签:
【中文标题】Wininet 客户端端口 - delphi 2010【英文标题】:Wininet client port - delphi 2010 【发布时间】:2011-03-03 22:05:00 【问题描述】:当我建立到服务器的套接字连接时,客户端和服务器都打开了套接字。很容易知道什么是服务器端口(因为我用它来连接服务器)。但是我想在连接到服务器后发现连接的客户端端口。我在 Delphi 2010 应用程序中使用 Wininet 函数。
伪代码:
1 - 互联网开放 2 - 互联网连接 3 - HttpOpenRequest 4 - HttpSendRequestA 5 - InternetReadFile 6 - ??????
已编辑:
我发现我应该将 InternetQueryOption 与 INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO 一起使用,但我不知道该怎么做。
【问题讨论】:
【参考方案1】:关于使用带有INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO
标志的InternetQueryOption
函数是正确的,这将返回INTERNET_DIAGNOSTIC_SOCKET_INFO Structure
typedef struct
DWORD_PTR Socket;
DWORD SourcePort;
DWORD DestPort;
DWORD Flags;
INTERNET_DIAGNOSTIC_SOCKET_INFO, * LPINTERNET_DIAGNOSTIC_SOCKET_INFO;
在 Delphi 中是这样的
PINTERNET_DIAGNOSTIC_SOCKET_INFO = ^TINTERNET_DIAGNOSTIC_SOCKET_INFO;
TINTERNET_DIAGNOSTIC_SOCKET_INFO= record
Socket : DWORD_PTR;
SourcePort : DWORD;
DestPort : DWORD;
Flags : DWORD;
end;
然后你可以写一个函数来返回套接字信息
function GetSocketInfo(hInet: HINTERNET) : TINTERNET_DIAGNOSTIC_SOCKET_INFO;
var
lpdwBufferLength: DWORD;
begin
lpdwBufferLength:=SizeOf(TINTERNET_DIAGNOSTIC_SOCKET_INFO);
ZeroMemory(@Result,lpdwBufferLength);
if not InternetQueryOption(hInet, INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, @Result, lpdwBufferLength) then
RaiseLastOSError;
end;
查看此示例应用以了解如何使用它。
$APPTYPE CONSOLE
uses
Windows,
WinInet,
SysUtils;
type
PINTERNET_DIAGNOSTIC_SOCKET_INFO = ^TINTERNET_DIAGNOSTIC_SOCKET_INFO;
TINTERNET_DIAGNOSTIC_SOCKET_INFO= record
Socket : DWORD_PTR;
SourcePort : DWORD;
DestPort : DWORD;
Flags : DWORD;
end;
const
INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO = Cardinal(67);
function GetSocketInfo(hInet: HINTERNET) : TINTERNET_DIAGNOSTIC_SOCKET_INFO;
var
lpdwBufferLength: DWORD;
begin
lpdwBufferLength:=SizeOf(TINTERNET_DIAGNOSTIC_SOCKET_INFO);
ZeroMemory(@Result,lpdwBufferLength);
if not InternetQueryOption(hInet, INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, @Result, lpdwBufferLength) then
RaiseLastOSError;
end;
//this a dummy function to download a file, only to show the use of the INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO
procedure WinInet_HttpGet(const Url: string);
const
BuffSize = 1024*1024;
var
hInter : HINTERNET;
UrlHandle: HINTERNET;
BytesRead: DWORD;
Buffer : Pointer;
SocketInfo: TINTERNET_DIAGNOSTIC_SOCKET_INFO;
begin
hInter := InternetOpen('', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(hInter) then
begin
GetMem(Buffer,BuffSize);
try
UrlHandle := InternetOpenUrl(hInter, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);
if Assigned(UrlHandle) then
begin
//Get the info of the socket
SocketInfo:=GetSocketInfo(UrlHandle);
Writeln('Socket Info');
Writeln(Format('Source Port %d',[SocketInfo.SourcePort]));
Writeln(Format('Dest Port %d',[SocketInfo.DestPort]));
try
repeat
InternetReadFile(UrlHandle, Buffer, BuffSize, BytesRead);
if BytesRead>0 then
begin
//do your stuff
end;
until BytesRead = 0;
finally
InternetCloseHandle(UrlHandle);
end;
end;
finally
FreeMem(Buffer);
end;
InternetCloseHandle(hInter);
end
end;
begin
try
WinInet_HttpGet('http://msdn.microsoft.com/en-us/library/aa385096%28v=vs.85%29.aspx');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.
【讨论】:
哇!!你真的很规则。感谢这个非常完整的解决方案。我一直在寻找有关 wininet 的好文档,但到目前为止我一无所获。你有什么好的文件吗? 顺便说一句,我真的很喜欢你的博客。以上是关于Wininet 客户端端口 - delphi 2010的主要内容,如果未能解决你的问题,请参考以下文章