
Параметры
hi_f d |
Число, на единицу большее номера самого старшего дескриптора в списке |
readfds |
Список дескрипторов каналов, из которых осуществляется чтение данных |
writefds |
Список дескрипторов каналов, в которые осуществляется запись данных |
exceptfds |
Список дескрипторов каналов, предназначенных для чтения внеполосных сообщений |
timeout |
Число микросекунд, в течение которых необходимо ждать изменений; параметр пред |
|
ставляет собой указатель на число; если это число (не указатель) равно нулю, функция |
|
немедленно завершается после проверки всех дескрипторов, если же сам указатель |
|
равен NULL (0), то период ожидания отсутствует (функция ждет бесконечно долго) |
f d |
Дескриптор канала, добавляемого, удаляемого или проверяемого |
set |
Список дескрипторов |
Возможные ошибки |
|
EBADF |
В один из списков входит неправильный дескриптор |
EINTR |
Получен неблокируемый сигнал |
EINVAL |
Указан отрицательный размер списка |
ENOMEM |
Не хватает памяти для создания внутренних таблиц |
Пример
int i, ports[]={9001, 9002, 9004, 1}; int sockfd, max=0;
fd_set set;
struct sockaddr_in addr;
struct timeval timeout={2,500000}; /* 2,5 секунды */
FD_ZERO(&set); bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY; for ( i = 0; ports[i] > 0; i
sockfd = socket(PF_INET, SOCK_STREAM, 0); addr.sin_port = htons(ports[i] );
if ( bind(sockfd, &addr, sizeof(addr)) != 0 ) perror("bind() failed");
else
{
FD_SET(sockfd,&set); if ( max < sockfd ) max = sockfd;
}
}
if ( select(max+l, &set, 0, &set, &timeout) > 0 )
{
for ( i=0; i<=max; i++)
Приложение В. API функции ядра |
431 |
Ⱦɚɧɧɚɹ ɜɟɪɫɢɹ ɤɧɢɝɢ ɜɵɩɭɳɟɧɚ ɷɥɟɤɬɪɨɧɧɵɦ ɢɡɞɚɬɟɥɶɫɬɜɨɦ %RRNV VKRS Ɋɚɫɩɪɨɫɬɪɚɧɟɧɢɟ ɩɪɨɞɚɠɚ ɩɟɪɟɡɚɩɢɫɶ ɞɚɧɧɨɣ ɤɧɢɝɢ ɢɥɢ ɟɟ ɱɚɫɬɟɣ ɁȺɉɊȿɓȿɇɕ Ɉ ɜɫɟɯ ɧɚɪɭɲɟɧɢɹɯ ɩɪɨɫɶɛɚ ɫɨɨɛɳɚɬɶ ɩɨ ɚɞɪɟɫɭ piracy@books-shop.com
if ( FD_ISSET(i, &set) )
{int client = accept(i, 0, 0);
/*** обрабатываем клиентский запрос ***/
}
}
write()
Функция write() записывает указанное число байтов из буфера в файл с деск риптором fd. Можно работать как с файлами, так и с сокетами, но во втором случае предпочтительнее использовать функцию send().
Прототип
#include <unistd.h>
int write(int fd, const void *buffer, size_t msg_len);
Возвращаемое значение
Функция возвращает число записанных байтов. Это число может быть мень ше, чем значение параметра msg_len. Если функции не удалось за один заход за писать требуемое число байтов, ее можно вызывать в цикле до тех пор, пока опе рация не будет завершена. В случае ошибки возвращается отрицательное значе ние, а в переменную errno помещается код ошибки.
Параметры
f d |
Дескриптор файла или сокета |
buffer |
Буфер, содержащий сообщение |
msg_len |
Длина сообщения |
Возможные ошибки |
|
EBADF |
Указан неверный дескриптор файла либо файл не открыт для записи |
EINVAL |
Указанный дескриптор связан с объектом, запись в который невозможна |
EFAULT |
Указатель buffer содержит неправильный адрес |
EPIPE |
Дескриптор связан с каналом или сокетом, который закрыт на противоположной сторо |
|
не; в этом случае процессу, осуществляющему запись, посылается сигнал SIGPIPE, и |
|
если он его принимает, функция write() генерирует ошибку EPIPE |
EAGAIN |
Задан режим неблокируемого ввода вывода (с помощью флага 0_NONBLOCK), а в буфере |
|
канала или сокета нет места для немедленной записи данных |
EINTR |
Функция была прервана сигналом до того, как началась запись данных |
ENOSPC |
В буфере устройства, содержащего файл с указанным дескриптором, нет места для за |
|
писи данных |
ЕЮ |
При модификации индексного дескриптора произошла низкоуровневая ошибка ввода |
|
вывода |
432 |
Часть V. Приложения |
www.books-shop.com
Пример
/*** Запись сообщения (TCP, UDP, неструктурированное) ***/
int sockfd;
int bytes, bytes_wrote=0;
/*— Создание сокета, подключение к серверу —*/ while ((bytes = write(sockfd, buffer, msg_len)) > 0 )
if ((bytes_wrote += bytes) >= msg_len) break;
if ( bytes < 0 ) perror("write");
close()
Функция close() закрывает любой дескриптор (как файла, так и сокета). Если сокет подключен к серверу или клиенту, канал остается активным после закры тия до тех пор, пока не произойдет очистка буферов или не будет превышен пе риод ожидания. Для каждого процесса устанавливается лимит числа открытых де скрипторов. В Linux 2.2.14 функция getdtablesize() возвращает значение 1024, а в файле /usr/include/linux/limits.h этот параметр определен в константе NR_OPEN.
Прототип
#include <unistd.h> int close(int fd);
Возвращаемое значение
Вслучае успешного завершения возвращается нуль. Если произошла ошибка,
еекод записывается в переменную errno.
Параметр |
|
f d |
Дескриптор файла или сокета |
Возможная ошибка |
|
EBADF |
Указан неверный дескриптор файла |
Пример
int sockfd;
sockfd = socket(PF_INET, SOCK_RAW, htons(99)); if ( sockfd < 0 )
PANIC("Raw socket create failed");
if ( close(sockfd) != 0 )
PANIC("Raw socket close failed");
Приложение В. API функции ядра |
433 |
www.books-shop.com
Приложение Вспомогательные
Гклассы
В этом приложении.
Исключения C++ |
449 |
Служебные классы C++ |
450 |
КлассысообщенийC++ |
451 |
Классы сокетов C++ |
452 |
Исключения Java |
456 |
Служебные классы Java |
457 |
Классы ввода вывода Java |
458 |
Классы сокетов Java |
464 |
www.books-shop.com
В этом приложении описаны классы, определенные в Java API, а также в поль зовательской библиотеке сокетов C++, которую мы создавали в главе 13, "Программирование сокетов в C++" (полное ее описание имеется на Web узле). Каждый класс сопровождается одним из трех обозначений; класс (обычный класс, экземпляры которого можно создавать), абстрактный класс (класс, определяю щий лишь интерфейс для производных классов) и подкласс (родительский класс верхнего уровня, экземпляры которого можно создавать).
Исключения С++
Ниже описаны классы объектов исключений, определенные в пользователь ской библиотеке сокетов.
Exception < RangeException
< FiteExceptton
< NetException <: NetCoriversionExceptton
< NetDNSException
< NetlOException
< NetConnectException
< NetConfigException
Рис. Г.1. Иерархия классов исключений в C++
Exception (надкласс)
Конструктор:
Exception(SimpleStrings);
Общее описание: исключение общего характера. Метод:
const char* Getstring(); |
Возвращает строку сообщения |
Дочерние исключения: |
|
RangeException |
Любое исключение, связанное с выходом за пределы массива; гене |
|
рируется классом MessageGroup |
FileException |
Любое исключение, связанное с обработкой файла; генерируется |
|
классом Socket |
NetException |
(класс) |
Конструктор: |
|
NetException(SimpleString s);
Общее описание: исключение общего характера при работе в сети. Родительский класс:Exception
Дочерние исключения:
Приложение Г. Вспомогательные классы |
435 |
www.books-shop.com
NetConversionException |
Исключение, связанное с преобразованием адреса узла (функции |
|
inet_ntop()/inet_pton()); генерируется классом HostAddress |
NetDNSException |
Исключение, связанное с невозможностью определения имени узла; |
|
генерируется классом HostAddress |
NetIOException |
Исключение при выполнении функций send()/recv(); генерируется |
|
классом Socket |
NetConnectException |
Исключение при выполнении функции bind(), connect(), |
|
listen() или accept(); генерируется классами SocketServer, |
|
SocketClient и MessageGroup |
NetConf igException |
Исключение при попытке задания/получения параметров сокета; ге |
|
нерируется всеми классами семейства Socket |
Служебные классы C+ +
Ниже описаны некоторые классы пользовательской библиотеки сокетов, но сящие служебный характер. При необходимости их можно заменить стандартны ми классами C++.
SimpleString (класс)
Конструктор:
SimpleString(const char* s);
SimpleString(const SimpleString& s);
Общее описание: очень простой строковый тип данных. Методы:
+ (char *); |
Добавляет строку к текущему экземпляру класса |
+(SimpleString& ); |
|
const char* GetString(); |
Возвращает строку сообщения |
Генерируемые исключения: (отсутствуют)
HostAddress (класс)
Конструктор:
HostAddress(const char* Name=0, ENetwork Network=eIPv4);
HostAddress(HostAddressS Address);
Общее описание: класс, предназначенный для управления адресами узлов. Методы:
void SetPort(int |
Port); |
Задает номер порта |
int GetPort(void) |
const; |
Возвращает номер порта, |
ENetwork GetNetwork(void) |
Возвращает тип сети |
|
const; |
|
|
436 |
|
Часть V. Приложения |
www.books-shop.com
struct sockaddr* |
Возвращает реальный адрес сокета |
|
GetAddress(void)const; |
|
|
int Getsize(void) const; |
Возвращаетразмер адреса сокета |
|
int |
==(HostAddresss |
Проверка на равенство |
Address) const; |
|
|
int |
!=(HostAddresss |
Проверка на неравенство |
Address) const; |
' |
|
const char* GetHost(bool |
Возвращает имя узла |
|
byName=l); |
|
Генерируемыеисключения:
Exception
NetConversionException
NetDNSException
Классы сообщений C+ +
Благодаря описанным ,ниже классам можно создавать классы, которые само стоятельно упаковывают и распаковывают собственные данные.
Message (абстрактный класс)
Конструктор: (отсутствует).
Общее описание: шаблон для создания отправляемого или принимаемого со общения.
Методы: |
|
virtual char* Wrap(int& Bytes) |
Интерфейс упаковки объектов |
const; |
|
bool Unwrap(char* package, int |
Интерфейс распаковки объектов |
Bytes, int MsgNum); |
|
Генерируемые исключения: (отсутствуют).
TextMessage (класс)
Конструктор:
TextMessage(unsignedshortBytes);
TextMessage(const char* Msg, unsigned short Len);
Общее описание: шаблон для создания текстового сообщения. Родительскийкласс:Message
Приложение Г. Вспомогательные классы |
437 |
www.books-shop.com
Методы: |
|
|
|
|
=(const |
char* |
str); |
|
Записывает новую строку в объект |
=(const |
TextMessage* |
s); |
|
|
+=(const |
char* |
str); |
|
Добавляет новую строку к объекту |
+=(const |
TextMessages |
s); |
|
|
const char* GetBuffer(void) const; |
Возвращает строку сообщения |
|||
char* Wrapfints Bytes) const; |
Упаковывает объект для отправки |
|||
bool Unwrap(char* package, int |
Распаковывает полученный объект |
|||
Bytes, int MsgNum); |
|
|
||
GetSize(void) const; |
|
Возвращает длину строки |
||
void SetSize(int Bytes); |
Задает длину строки |
|||
int GetAvailable(void) const; |
Возвращает число байтов, доступных в буфере |
Генерируемые исключения: (отсутствуют).
Классы сокетов C++
Ниже описаны классы, формирующие интерфейс сокетов. Для непосредствен ного создания объектов предназначены пять классов: SocketServer, SocketClient, Datagram, Broadcast и MessageGroup. Можно легко расширить иерархию за счет клас сов библиотеки OpenSSL (SSLServer и SSLClient).
Socket < SocketStream < SocketServer
< SocketClient
< Datagram < Broadcast
< MessageGroup
Рис. Г.2. Иерархия класса Socket в C++
Socket (надкласс)
Конструктор:
Socket(void);
Socket(int sd);
Socket(ENetwork Network, EProtocol Protocol);
Socket(Sockets sock);
Общее описание: класс, содержащий базовые функции работы с сокетами и не предназначенный для прямого создания объектов.
Методы:
void Bind(HostAddress& Addr); |
Связывает сокет с портом/интерфейсом |
void CloseInput(void) const; |
Закрывает входной поток |
voidCloseOutput(void) const; |
Закрывает выходной поток |
438 |
Часть V. Приложения |
www.books-shop.com
int Send(Message& Msg, int Options=0) const;
int Send(HostAddress& Addr, Messages Msg, int Options=0) const;
int Receive(Message& Msg, |
int |
||||
Options=0) const; |
|
|
|
||
int |
Receive(HostAddress& |
Addr, |
|||
Messages Msg, int Options=0) |
|||||
const; |
|
|
|
|
|
void |
PermitRoute(bool Setting); |
||||
void |
KeepAlive(bool |
Setting); |
|||
void |
ShareAddress(bool |
Setting); |
|||
int |
GetReceiveSize(void); |
||||
void |
SetReceiveSizefint |
Bytes); |
|||
int |
GetSendSize(void); |
|
|
||
void |
SetSendSize(int |
Bytes); |
|||
int |
GetMinReceive(void); |
|
|||
void |
SetMinReceive(int |
Bytes); |
|||
int |
GetMinSend(void); |
|
|
||
void |
SetMinSend(int |
Bytes); |
|||
struct timeval |
|
|
|
||
GetReceiveTimeout(void); |
|
|
|||
void |
SetReceiveTimeout(struct |
||||
timevals |
val); |
|
|
|
|
struct timeval |
|
|
|
||
GetSendTimeout(void); |
|
|
|||
void |
SetSendTimeout(struct |
||||
timeval& |
val); |
|
|
|
|
ENetwork |
GetType(void); |
|
|
virtual int GetTTL(void); virtual void SetTTL(int Hops);
int GetError(void);
Генерируемые исключения:
NetException
FileException
NetConnectException
NetIOException
NetConf igException
Посылает сообщение подключенному узяу
Посылает направленное сообщение
Принимает сообщение от подключенного узла
Принимает направленное сообщение
Разрешаетмаршрутизациюпакетов Удерживает соединение активным
Задает режим совместного использования адреса пор та/интерфейса
Возвращает/задает размер входного буфера
Возвращает/задаетразмервыходногобуфера
Возвращает/задаетпороговыйразмервходногобуфера для получения сигнала SIGIO
Возвращает/задаетпороговыйразмервыходногобуфера для получения сигнала SIGIO
Возвращает/задает период ожидания, по истечении ко торого прием данных будет прерван
Возвращает/задаетпериодожидания,поистечениико торого отправка данных будет прервана
Возвращаеттипсокета(сети)
Возвращает/задает предельное число переходов
Возвращает сообщение об ошибке, находящееся в оче реди
Приложение Г. Вспомогательные классы |
439 |
www.books-shop.com
SocketStream (класс)
Конструктор: |
|
|
SocketStream(void); |
|
|
SocketStrearn(int sd); |
|
|
SocketStream(ENetwork |
Network); |
|
SocketStream(SocketStreamssock); |
||
Общее описание: |
класс, |
определяющий интерфейс потоковых сокетов |
(SOCK_STREAM). |
|
|
Родительский класс: Socket |
|
|
Методы: |
|
|
int GetMaxSegmentSize(void); |
Возвращает/задает максимальный размер сегмента |
|
void SetMaxSegmentSize(short Bytes); |
||
void DontDelay(bool Setting); |
Включает/отключает алгоритм Нейгла |
Генерируемое исключение: NetConfigException
SocketServer(класс)
Конструктор:
SocketServer(int port, ENetwork Network=eIPv4, int QLen=15);
SocketServer(HostAddressS Addr, int QLen=15);
Общее описание: TCP сервер. |
|
|
Родительский класс: SocketStream |
|
|
Методы: |
|
|
void Accept(void (*Servlet) (const |
Принимает запрос на подключение и вызывает функ |
|
Sockets Client)); |
цию |
Servlet(), передавая ей объект Socket |
void Accept (HostAddressS |
Addr, void |
Принимает запрос на подключение, определяя адрес |
(*Servlet)(const Sockets |
Client)); |
вызова |
Генерируемые исключения:
Exception
NetConnectException
SocketClient (класс)
Конструктор:
SocketClient(ENetwork Network=eIPv4);
SocketClient(HostAddress& Host, ENetwork Network=eIPv4);
440 |
Часть V. Приложения |
www.books-shop.com