Wininet клиентский порт - Delphi 2010 - PullRequest
0 голосов
/ 04 марта 2011

Когда я устанавливаю сокет-соединение с сервером, сокеты и на клиенте, и на сервере открываются. Легко узнать, что такое порт сервера (поскольку я использую его для подключения к серверу). Но я хотел бы узнать клиентский порт подключения после подключения к серверу. Я использую функции Wininet в приложении Delphi 2010.

Псевдо-код:

1 - InternetOpen
2 - InternetConnect
3 - HttpOpenRequest
4 - HttpSendRequestA
5 - InternetReadFile
6 - ?????? <------ Как получить клиентский порт? </p>

Отредактировано:

Я обнаружил, что должен использовать InternetQueryOption с INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, но я понятия не имею, как это сделать.

1 Ответ

3 голосов
/ 04 марта 2011

вы правы относительно использования функции InternetQueryOption с флагом INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO, это вернет 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...