Wininet 客户端端口 - delphi 2010

发布于 2024-10-20 08:24:19 字数 402 浏览 7 评论 0原文

当我建立到服务器的套接字连接时,客户端和服务器都打开了套接字。很容易知道服务器端口是什么(因为我使用它来连接到服务器)。但我想在连接到服务器后发现连接的客户端端口。我在 Delphi 2010 应用程序中使用 Wininet 函数。

伪代码:

1 - InternetOpen
2 - 互联网连接
3 - HttpOpenRequest
4 - HttpSendRequestA
5 - 互联网读取文件
6 - ?????? <------ 如何获取客户端端口?

已编辑:

我发现我应该将 InternetQueryOption 与 INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO 一起使用,但我不知道该怎么做。

When I establish a socket connection to a server, both client and server have sockets opened. Its easy to know what is the server port (since I use it to connect to the server). But I would like to discover the client port of the connection after connecting to a server. I am using Wininet functions in a Delphi 2010 application.

Pseudo-code:

1 - InternetOpen
2 - InternetConnect
3 - HttpOpenRequest
4 - HttpSendRequestA
5 - InternetReadFile
6 - ?????? <------ How to get the client port?

Edited:

I have found I should use InternetQueryOption with INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, but i have no idea how to do that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧梦荧光笔 2024-10-27 08:24:19

您关于使用 InternetQueryOption< 的说法是正确的/code>函数带有 INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO 标志,这将返回 INTERNET_DIAGNOSTIC_SOCKET_INFO 结构

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.

you are correct about use the InternetQueryOption function with the INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO flag, this will return a INTERNET_DIAGNOSTIC_SOCKET_INFO Structure

typedef struct {
  DWORD_PTR Socket;
  DWORD     SourcePort;
  DWORD     DestPort;
  DWORD     Flags;
} INTERNET_DIAGNOSTIC_SOCKET_INFO, * LPINTERNET_DIAGNOSTIC_SOCKET_INFO;

which in Delphi look like this

PINTERNET_DIAGNOSTIC_SOCKET_INFO = ^TINTERNET_DIAGNOSTIC_SOCKET_INFO;
TINTERNET_DIAGNOSTIC_SOCKET_INFO=  record
  Socket     : DWORD_PTR;
  SourcePort : DWORD;
  DestPort   : DWORD;
  Flags      : DWORD;
end;

and then you can wrote a function to return the socket info

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;

check this sample app to see how use it.

{$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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文