【问题标题】:Wininet client port - delphi 2010Wininet 客户端端口 - 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 一起使用,但我不知道该怎么做。

【问题讨论】:

    标签: delphi sockets delphi-2010 wininet


    【解决方案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 的好文档,但到目前为止我一无所获。你有什么好的文件吗?
    • 顺便说一句,我真的很喜欢你的博客。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    相关资源
    最近更新 更多