Функция WSAAsyncSelect переводит гнездо s в асинхронный режим. Параметры HWindow и wMsg - дескриптор окна, принимающего сообщения о событии и идентификатор этого события соответственно; параметр lEvent определяет, при возникновении каких событий гнездо посылает сообщение (lEvent суть комбинация двоичных флагов, см. табл. ниже).
Символ флага |
Значение |
Событие |
FD_READ |
$01 |
Имеются данные для приема |
FD_WRITE |
$02 |
Имеются данные в буфере для отправления |
FD_OOB |
$04 |
|
FD_ACCEPT |
$08 |
Запрос на соединение для приема |
FD_CONNECT |
$10 |
Соединение с удаленной ЭВМ завершено |
FD_CLOSE |
$20 |
Соединение закрыто |
Для настройки разрешения гнезду посылать сообщения о нескольких событиях необходимо объединить флаги этих событий с помощью поразрядного оператора OR. Например, в нижеследующем примере гнезду OpenSocket_001 разрешается посылать определенное пользователем событие UWM_SOCKETEVENT окну с идентификатором handle_001 каждый раз, когда гнездо OpenSocket_001 закрывается удаленной ЭВМ, но при этом имеет поступающие данные для приема или место в буфере для отправления данных
WSAAsyncSelect(OpenSocket_001, handle_001;
UWM_SOCKETEVENT,
FD_CONNECT or FD_READ or
FD_WRITE or FD_CLOSE);
Программист должен самостоятельно разработать процедуру-обработчик данного сообщения, памятуя, что вышеопределенный FD-флаг помещается в атрибут LParamHi объекта TMessage. При вощникновении события в атрибут LParamLo объекта TMessage помещается константа SOCKET_ERROR (см. пример)
procedure TForm_001.UWM_SocketEvent(varMsg: TMessage)
{ возникла какая-то ошибка ? }
begin
if (Msg.LParamHi = SOCKET_ERROR ) then { ошибка сокета ! }
Process_SocketError { обработка ошибки сокета }
else
begin
{ ошибки нет, выполнить обработку соответствующих ситуаций }
case Msg:LparamLO of
FD_CONNECT: Process_FD_CONNECT; { обработчики... }
FD_READ: Process_FD_READ;
FD_WRITE: Process_FD_WRITE;
FD_CLOSE: Process_FD_CLOSE;
end;
end;
end; { конец процедуры UWM_SocketEvent }
6. Поиск адреса удаленного компьютера. Используются функции типа (где name - имя удаленного компьютера для поиска, buf - буфер для приeма найденного адреса ЭВМ) :
function
WSAAsyncGetHostByName(HWindow: HWND; wMsag: u_int;
name, buf: PChar; buflen: Integer);
THandle;
Другими функциями этой группы являются WSAAsyncGetHostByAddr(), WSAGetServByName(), WSAGetServByPort(), WSAGetProtoByName(), WSAGetProtoByNumber().
Получить адрес и порт сокета s на данной ЭВМ можно с помощью функции (адрес помещается в name)
function
getsockname(s: TSocket; var name: TSockaddr;
var namelen: Integer): Integer;
а сокета на удаленной ЭВМ, к которому в данный момент подключены
function
getpeername(s: TSocket; var name: TSockaddr;
var namelen: Integer): Integer;
6.Технология сокетов применяется и для работы с протоколом UDP (User Datagram Protocol). В отличие от TCP/IP (Transmission Control Protocol / Intenet Protocol ) протокол UDP не гарантирует доставку пакетов и допускает нарушение исходного порядка сообщений (допускается также случайное дублирование пакетов). Программист обязан в этом случае проводить контроль данных на уровне прикладной программы, для чего потребуется организация подтверждения доставки и повторная пересылка данных.
Для сокетов UDP существуют две новых функции (нижеприводятся в С-стиле). Эти вызовы могут быть использованы и при работе с TCP/IP, но обычно применяются в UDP-модели (чтобы сервер мого получить информацию об отправителе и послать ответ). Тип сокета (TCP/IP или UDP) определяется параметрами type и protocol в момент вызова soket); при protocol=0 в случае type=SOCK_STREAM используется протокол TCP/IP, а при type=SOCK_DGRAM - протокол UDP.
N0 |
Используемая функция |
Описание действия |
1. |
ssize_t recvfrom(int sockfd, void *buff, size_t length, int flags, struct sockaddr *send_addr, size_t *add_len); |
Прием UDP-пакетов через гнездо sockfd в буфер buff длиной length. Адрес и порт, откуда пришли данные, запоминаются (для последующего ответа) в структуре send_addr длиной add_len (при send_addr=NULL вызов recvfrom абсолютно аналогичен вышеприведенному recv) |
2. |
ssize_t sendto(int sockfd, const void *buff, size_t length, int flags, const struct sockaddr *dest_addr, size_t *dest_len); |
Передача UDP-пакетов через гнездо sockfd из буфера buff длиной length. Данные передаются на адрес и порт, заданные структурой dest_addr размером dest_len |
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.