Метод TCsSocket SetRemoteHostName
procedure TCsSocket.SetRemoteHostName(NameReqd : String);
var P : Pointer; IPAddress : LongInt; begin FRemoteName := NameReqd; if Length(NameReqd) = 0 then begin FStatus := Failure; ErrorEvent(FStatus, 'No host name given!');
case FLookUpOp of resHostName : LookUpEvent(resHostName, FRemoteName, FALSE);
resIPAddress : LookUpEvent(resIPAddress, FRemoteName, FALSE);
end;// case raise ECsSocketError.create('No host name given!');
Exit; end; if FAccess = NonBlocking then SetAsyncHostName(FRemoteName) else begin InfoEvent('Resolving host');
StrPCopy(FpHostName, FRemoteName);
{ Определяем тип введенного адреса } IPAddress := inet_addr(FpHostName);
if IPAddress <>
INADDR_NONE then { Это IP-адрес } begin FLookUpOp := resHostName; FAddress := IPAddr; P := addr(IPAddress);
case AddrType of AFINET : FHost := gethostbyaddr(P, 4, AF_INET);
end; end else { Нет, это больше похоже на символьное имя хоста } begin FLookUpOp := resIPAddress; FAddress := HostAddr; FHost := gethostbyname(FpHostName);
end; if FHost = NIL then begin{ Неизвестный хост, отменяем попытку...} LookUpEvent(FLookUpOp, '', FALSE);
FStatus := Failure; if FOKToDisplayErrors then raise ECsSocketError.create('Unable to resolve ' + FpHostName);
Exit; end; InfoEvent('Host found');
FStatus := Success; Move(FHost^.h_addr_list^, Fh_addr, SizeOf(FHost^.h_addr_list^));
if FAddress = HostAddr then begin SetUpAddress; FRemoteName := StrPas(inet_ntoa(FSockAddress.sin_addr));
end else if FAddress = IPAddr then begin FRemoteName := StrPas(FHost^.h_name);
InfoEvent('Host found...');
end; case FLookUpOp of resHostName : LookUpEvent(resHostName, FRemoteName, TRUE);
resIPAddress : LookUpEvent(resIPAddress, FRemoteName, TRUE);
end;// case end; end;
Затем метод SetRemoteHostName с помощью функции inet_addr проверяет, не содержит ли исходная строка числового IP-адреса. Если не содержит, метод предполагает, что в ней находится имя хоста, и вызывает функцию gethostbyname для преобразования его в IP-адрес. Если имя хоста отсутствует в локальном файле хостов, gethostbyname ищет имя в удаленном файле хостов, хранящемся в сети.
Если имя не найдено, процесс поиска прекращает работу по тайм-ауту и присваивает protected-свойству FHost (которое представляет собой указатель на структуру pHostent) значение NIL. Затем SetRemoteHostName вызывает обработчик события LookUpEvent, чтобы сообщить о неудачном завершении просмотра, присваивает флагу FStatus значение Failure и возвращает управление вызывающему приложению. При удачном завершении поиска функция gethostbyname возвращает указатель на FHost, где содержится найденный адрес. Наконец, SetRemoteHostName возвращает IP-адрес в виде строки Паскаля, для чего используется следующий оператор:
FRemoteName := StrPas(inet_ntoa(FSockAddress.sin_addr));
Функция inet_itoa переводит возвращаемый IP-адрес в строку с нуль-терминатором, а функция StrPas завершает преобразование в строку Паскаля. Адресная информация сокета размещается в поле FSockAddress, откуда она позднее извлекается для установки соединения с хостом. Полученный в результате поиска IP-адрес помещается в текстовое поле edIPName (см. Рисунок 5.4). Для этого RESOLVER32 использует обработчик события OnLookUp, который вызывается внутри процедуры LookUpEvent. В листинге 5.8 показано, как это делается.