Процедура AsyncOperation
procedure TCsSocket.AsyncOperation(var Mess : TMessage);
var MsgErr : Word; begin if Mess.Msg = ASYNC_EVENT then begin MsgErr := WSAGetAsyncError(Mess.lparam);
if MsgErr <>
0 then begin FStatus := Failure; ErrorEvent(FStatus,WSAErrorMsg);
if FOKToDisplayErrors then raise ECsSocketError.create(WSAErrorMsg);
Exit; end else begin FStatus := Success; InfoEvent('WSAAsync operation succeeded!');
case FAsyncType of AsyncName, AsyncAddr : begin FHost := pHostent(@FAsyncBuff);
if (FHost^.h_name = NIL) then begin { Неизвестный хост, отменяем попытку... } FStatus := Failure; if FAsyncType = AsyncName then LookUpEvent(resIPAddress,'',FALSE) else LookUpEvent(resHostName,'',FALSE);
if FOKToDisplayErrors then raise ECsSocketError.create ('Unable to resolve host');
Exit; end; if length(StrPas(FHost^.h_name)) = 0 then begin InfoEvent('Host lookup failed!');
FStatus := Failure; if FAsyncType = AsyncName then LookUpEvent(resIPAddress,'',FALSE) else LookUpEvent(resHostName,'',FALSE);
if FOKToDisplayErrors then raise ECsSocketError.create ('Unknown host');
Exit; end; case FAddress of IPAddr : begin Move(FHost^.h_addr_list^, Fh_addr, SizeOf(FHost^.h_addr_list^));
FAsyncRemoteName := StrPas(FHost^.h_name);
LookUpEvent(resHostName, FAsyncRemoteName, TRUE);
end; HostAddr : begin Move(FHost^.h_addr_list^, Fh_addr, SizeOf(FHost^.h_addr_list^));
SetUpAddress; FAsyncRemoteName:= StrPas(inet_ntoa(FSockAddress. sin_addr));
LookUpEvent(resIPAddress,FAsyncRemoteName, TRUE);
end; end;{case} end; AsyncServ : begin FServ := pServent(@FAsyncBuff);
if FServ^.s_name = NIL then begin { Сервис недоступен } FStatus := Failure; LookUpEvent(resService,'',FALSE);
if FOKToDisplayErrors then raise ECsSocketError.create(WSAErrorMsg);
Exit; end; FAsyncPort := IntToStr(ntohs(FServ^.s_port));
LookUpEvent(resService, FAsyncPort, TRUE);
end; AsyncPort : begin FServ := pServent(@FAsyncBuff);
if FServ^.s_name = NIL then begin { Сервис недоступен } FStatus := Failure; LookUpEvent(resPort,'',FALSE);
if FOKToDisplayErrors then raise ECsSocketError.create(WSAErrorMsg);
Exit; end; FAsyncService := StrPas(FServ^.s_name);
LookUpEvent(resPort, FAsyncService, TRUE);
end; AsyncProtoName : begin FProto := pProtoEnt(@FAsyncBuff);
if FProto^.p_name = NIL then begin FStatus := Failure; LookUpEvent(resProto,'',FALSE);
if FOKToDisplayErrors then raise ECsSocketError.create(WSAErrorMsg);
Exit; end; FAsyncProtoNo := IntToStr(FProto^.p_proto);
LookUpEvent(resProto, FAsyncProtoNo, TRUE);
end; AsyncProtoNumber : begin FProto := pProtoEnt(@FAsyncBuff);
if FProto^.p_name = NIL then begin FStatus := Failure; LookUpEvent(resProtoNo,'',FALSE);
if FOKToDisplayErrors then raise ECsSocketError.create(WSAErrorMsg);
Exit; end; FAsyncProtocol := StrPas(FProto^.p_name);
LookUpEvent(resProtoNo, FAsyncProtocol, TRUE);
end; end; if FNoOfBlockingTasks >
0 then dec(FNoOfBlockingTasks);
end; end; end;
Функция WSAGetAsyncError проверяет значение переменной Mess. Если переменная сообщает о происшедшей ошибке, AsyncOperation вызывает ErrorEvent для вывода причины ошибки из WSAErrorMsg, а затем завершает работу, присваивая флагу FStatus значение Failure. Если ошибки не было, мы анализируем переменную FAsyncType.
При вызове WSAAsyncGetHostByName мы присваиваем FAsyncType значение AsyncName, чтобы установить признак асинхронного поиска имени. Затем оператор case переходит к фрагменту, соответствующему значению AsyncName. Здесь символьный массив FAsyncBuff, содержащий результаты поиска, преобразуется в структуру pHostent и сохраняется в поле FHost. SetUpAddress читает адресную структуру найденного хоста и получает искомый IP-адрес. Наконец, процедура LookUpEvent возвращает IP-адрес программе RESOLVER32.