Флаг 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 говорит только о том, что данные были успешно переданы. Она никак не указывает, дошли ли они до места назначения.
Как только запрос передан, 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, обслуживающий прием данных через сокет:
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.