Глобальные сети компьютеров. Практическое введение в Internet


Приложение SERVERD - часть 6


Приложение SERVERD во многом напоминает приложение SERVER, поэтому мы рассмотрим только отличия.

Первое отличие заключается в том, что при запуске сервера тип создаваемого сокета указывается как SOCK_DGRAM:

srv_socket = socket(AF_INET , SOCK_DGRAM, 0);

Далее выполняется инициализация сокета и его привязка к адресу, для чего вызывается функция bind . Эта операция, как и в случае протокола TCP, не обязательна.

После выполнения привязки можно приступать к получению пакетов данных от клиента. Для того чтобы не выполнять ожидание пакетов в цикле, наше приложение использует функцию WSAAsyncSelect , указывая с ее помощью, что при получении пакетов данных главное окно приложения должно получать сообщения с кодом WSA_NETEVENT:

rc = WSAAsyncSelect (srv_socket , hWnd, WSA_NETEVENT, FD_READ );

На этом инициализация сервера завершается.

Обработчик сообщения WSA_NETEVENT читает полученный пакет с помощью функции recv from:

SOCKADDR _IN addr; int nAddrSize; rc = recv from((SOCKET)wParam, szTemp, 256, 0, (PSOCKADDR )&addr, &nAddrSize);

В качестве предпоследнего параметра этой функции передается адрес структуры типа SOCKADDR _IN, куда функция записывает адрес узла, приславшего пакет. Последний параметр функции recv from должен содержать размер указанной структуры.

Ниже мы привели возможные коды ошибок для функции recv from.

Код ошибки Описание
WSANOTINITIALISED Перед использованием функции необходимо вызвать функцию WSAStartup
WSAENETDOWN Сбой в сети
WSAEFAULT Слишком малое значение параметра, определяющего размер буфера для приема данных
WSAEINTR Работа функции была отменена при помощи функции WSACancelBlockingCall
WSAEINPROGRESS Выполняется блокирующая функция интерфейса Windows Sockets
WSAEINVAL Сокет не был подключен функцией bind
WSAENOTSOCK Указанный дескриптор не является дескриптором сокета
WSAESHUTDOWN Сокет был закрыт функцией shutdown
WSAEWOULDBLOCK Сокет отмечен как неблокирующий, но запрошенная операция приведет к блокировке
WSAEMSGSIZE Размер датаграммы слишком большой, поэтому соответствующий блок данных не помещается в буфер. Принятый блок данных был обрезан
WSAECONNABORTED Сбой из-за слишком большой задержки или по другой причине
WSAECONNRESET Сброс соединения удаленным узлом

Заметим, что при обмене данных с использованием протокола UDP на каждый вызов функции send to должен приходиться один вызов функции recv from. Если же вы передается данные через канал с использованием протокола TCP, на один вызов функции send может приходиться несколько вызовов функции recv.

Для отображения адреса узла, пославшего пакет UDP , наше приложение преобразует этот адрес в символьную строку с помощью функции inet_ntoa :

lpAddr = inet_ntoa (addr.sin_addr );

Эта функция записывает полученную строку в статическую область памяти, принадлежащую системе Windows Sockets, поэтому для дальнейшего использования необходимо скопировать строку до следующего вызова любой функции программного интерфейса Windows Sockets.




Начало  Назад  Вперед



Книжный магазин