Протокол Finger и информация о пользователях, страница 10

Флаг MSG_OOB требует, чтобы данные передавались (и, соответственно, принимались) как данные «вне диапазона». Если флаг MSG_OOB установлен с датаграммным сокетом, функция вернет сообщение об ошибке.

Функция send в программе QFinger вызывается с третьим параметром, равным SEND_FLAGS. Он, в свою очередь, равен нулю. Как уже отмечалось, сервер протокола Finger ожидает получить запрос в формате NVT ASCII с порта 79. Чтобы запросить информацию обо всех работающих в данный момент пользователях, достаточно передать запрос в виде пустой строки. Чтобы получить информацию о конкретном пользователе, нужно передать его имя, либо идентификатор. Каждый запрос должен заканчиваться маркером конца строки. В случае NVT ASCII, это будет комбинация CRLF, возврат каретки плюс перевод строки.

Текст запроса QFinger находится в константе FINGER_QUERY. Константа может содержать любое имя или идентификатор, лишь бы он был известен удаленному компьютеру по имени HOST_NAME. Если функция connect отработала успешно, QFinger при помощи функции wsprintf формирует запрос в буфере szFingerQuery, добавляя CRLF (\n) к FINGER_QUERY. Далее, функции send передается дескриптор nSocket, указатель на буфер szFingerQuery, длина буфера (вычисленная при помощи lstrlen) и флаги, определенные в SEND_FLAGS:

if (nConnect)

MessageBox(NULL, "Error connecting socket!!", PROG_NAME, MB_OK | MB_ICONSTOP) ;

else // Формируем и высылаем запрос Finger

{

wsprintf(szFingerQuery,"%s\n", FINGER_QUERY) ;

nCharSent = send(nSocket, szPingerQuery,

lstrlen(szPingerQuery), SEND_FLAGS) ;

if (nCharSent == SOCKET_ERROR)

MessageBox(NULL, "Error occurred during send()!", PROG_NAME,

MB_OK | MB_ICONSTOP) ;

Если все прошло успешно, функция send возвращает количество переданных байтов. Если нет, значение функции будет равно SOCKET_ERROR. Результат send присваивается переменной nCharSent, и ее значение проверяется. Если оно равно SOCKET_ERROR, выводится соответствующее сообщение и программа Оканчивает работу.

Примечание: Благополучное окончание функции send говорит только о том, что данные были успешно переданы. Она никак не указывает, дошли ли они до места назначения.

Прием ответного сообщения Finger

Как только запрос передан, QFinger переходит в цикл do-while, где периодически вызывает функцию recv, чтобы принять данные из сокета. Ниже показан прототип функции recv:

int PASCAL FAR recv(int s, char FAR * buf, int len, int flags);

Функция recv возвращает количество считанных из сокета байтов. Первый параметр recv — дескриптор сокета. Ему следовало бы иметь тип SOCKET, но поскольку SOCKET определен в winsock.h как беззнаковое целое (unsigned int), то определение первого аргумента recv как int вполне корректно. Как обычно, переменная nSocket хранит дескриптор сокета. Второй параметр — указатель на буфер для поступающих данных. Третий параметр — длина буфера. Если сокет потоковый и количество данных превышает размер буфера, все функционирует нормально — recv заполнит буфер на всю длину и возвратится. Если сокет датаграммный — излишние данные безвозвратно пропадут, а recv вернет значение ошибки.

В версии 1.1 спецификации Winsock определены два флага, которые можно указывать в качестве четвертого параметра. С одним из них, MSG_OOB, вы уже встречались. Второй, MSG_PEEK, указывает функции recv на то, что данные из входной очереди можно копировать в буфер как обычно, но при этом их нельзя стирать из входной очереди. В нормальной ситуации recv всегда стирает данные из входной очереди после того, как они переписаны в буфер.

Функции recv передаются дополнительные флаги, RECV_FLAGS, равные нулю. Ниже приведен фрагмент программы QFinger, обслуживающий прием данных через сокет: