Как проверить интернет соединение с помощью Winsock api? - PullRequest
0 голосов
/ 02 марта 2019

Я построил этот код ниже (на основе в этом примере), чтобы проверить, существует ли соединение с Интернетом, используя Winsock api и пытаясь сделать GET-запрос к определенному веб-сайту ( google.com в моем случае).

Но WSAGetLastError возвращает код ошибки: 10051 .

Как это исправить?

program Project1;

uses
  Windows, SysUtils, WinSock;

function GetIPFromHostName(const HostName: string): string;
var
  WSAData: TWSAData;
  R: PHostEnt;
  A: TInAddr;
begin
  Result := '0.0.0.0';
  WSAStartup($101, WSAData);
  R := GetHostByName(PAnsiChar(AnsiString(HostName)));
  if Assigned(R) then
  begin
    A := PInAddr(R^.h_Addr_List^)^;
    Result := WinSock.inet_ntoa(A);
  end;
end;

function IsConnectedToInternet: Boolean;
var
  WSAData1: TWSAData;
  SockAddr1: TSockAddr;
  Socket1: TSocket;
begin
  Result := False;

  if WSAStartup(MAKEWORD(2, 2), WSAData1) <> 0 then
  begin
    Writeln('WinSock error');
    Exit;
  end;

  Socket1 := Socket(AF_INET, SOCK_STREAM, 0);
  if Socket1 = INVALID_SOCKET then
  begin
    Writeln('socket error');
    Exit;
  end;

  SockAddr1.sin_family := AF_INET;
  SockAddr1.sin_addr.S_addr := inet_addr(PAnsiChar(GetIPFromHostName('google.com')));
  SockAddr1.sin_port := htons(80);

  if Connect(Socket1, SockAddr1, SizeOf(SockAddr1)) <> 0 then
  begin
    Writeln('connection error #', WSAGetLastError);
    Exit;
  end;

  Result := True;

  if CloseSocket(Socket1) <> 0 then
    Writeln('error closing socket');
end;

begin
  IsConnectedToInternet;
  readln;

end.

1 Ответ

0 голосов
/ 03 марта 2019

Компилятор предупреждает вас об ошибке, в строке, которую вы заполняете in_addr из sockaddr_in:

W1044 Подозрительный тип строки в PAnsiChar

inet_addr ожидает строку символов ANSI.Вы типизируете строку юникода в PAnsiChar и, таким образом, передаете искаженную строку, что приводит к connect невозможности найти пункт назначения.

заменить

SockAddr1.sin_addr.S_addr := inet_addr(PAnsiChar(GetIPFromHostName('google.com')));

на

SockAddr1.sin_addr.S_addr :=
    inet_addr(PAnsiChar(AnsiString(GetIPFromHostName('google.com'))));

Вы можете использовать один из API-интерфейсов, предназначенных для этой цели, например InternetCheckConnection, или InternetGetConnectedState, или INetworkListManager интерфейс (Vista и более поздние версии),

Например,

const
  FLAG_ICC_FORCE_CONNECTION = 1;
begin
  if not InternetCheckConnection('http://google.com', FLAG_ICC_FORCE_CONNECTION, 0) then
    RaiseLastOSError;
...