UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Важная характеристика срочного режима TCP заключается в следующем: заголовок TCP указывает на то, что отправитель вошел в срочный режим (то есть флаг URG установлен вместе со срочным смещением), но фактической отправки байта данных, на который указывает срочный указатель, не требуется. Действительно, если поток данных TCP остановлен функциями управления потоком (когда буфер приема сокета получателя заполнен и TCP получателя объявил нулевое окно для отправляющего TCP), то срочное уведомление отправляется без каких-либо данных [128, с. 1016–1017], как показано в листингах 24.8 и 24.9. Это одна из причин, по которой в приложениях используется срочный режим TCP (то есть внеполосные данные): срочное уведомление всегда отсылается собеседнику, даже если поток данных остановлен функциями управления потоком TCP.
Что произойдет, если мы отправим несколько байтов внеполосных данных, как в следующем примере?
send(fd, "abc", 3, MSG_OOB);
В этом примере срочный указатель TCP указывает на байт, следующий за последним байтом, и таким образом, последний байт (
с
Посмотрим теперь, как выглядит процесс отправки внеполосных данных с точки зрения принимающей стороны.
1. Когда TCP получает сегмент, в котором установлен флаг URG, срочный указатель проверяется для выяснения того, указывает ли он на новые внеполосные данные. Иначе говоря, проверяется, впервые ли этот конкретный байт передается в срочном режиме TCP. Дело в том, что часто отправляющий TCP посылает несколько сегментов (обычно в течение короткого промежутка времени), содержащих флаг URG, в которых срочный указатель указывает на один и тот же байт данных. Только первый из этих сегментов фактически уведомляет принимающий процесс о прибытии новых внеполосных данных.
2. Принимающий процесс извещается о том, что прибыли новые внеполосные данные. Сначала владельцу сокета посылается сигнал
SIGURG
fcntl
ioctl
select
Эти два уведомления действуют в том случае, когда прибывает новый срочный указатель, вне зависимости от того, принят ли байт, на который он указывает.
В потоке данных может быть только одна отметка OOB (один срочный указатель). Если новый срочный байт отправляется до того, как будет принят старый, последний просто сбрасывается и перестает быть срочным.
3. Когда байт данных, на который указывает срочный указатель, фактически прибывает на принимающий TCP, этот байт может быть помещен отдельно или оставлен вместе с другими данными. По умолчанию параметр сокета
SO_OOBINLINE
recv
recvfrom
recvmsg
MSG_OOB
Однако если процесс устанавливает параметр сокета
SO_OOBINLINE
MSG_OOB
1. Если процесс запрашивает внеполосные данные (то есть устанавливает флаг
MSG_OOB
EINVAL
2. Если процесс был уведомлен о том, что собеседник послал содержащий внеполосные данные байт (например, с помощью функции
select
SIGURG
EWOULDBLOCK
3. Если процесс пытается считать одни и те же внеполосные данные несколько раз, возвращается ошибка
EINVAL
4. Если процесс установил параметр сокета
SO_OOBINLINE
MSG_OOB
EINVAL
Простой пример использования сигнала SIGURG
Теперь мы рассмотрим тривиальный пример отправки и получения внеполосных данных. В листинге 24.1 [1] показана программа отправки этих данных.
Листинг 24.1. Простая программа отправки внеполосных данных
//oob/tcpsend01.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd;
6 if (argc != 3)
7 err_quit("usage: tcpsend01 <host> <port#>");
8 sockfd = Tcp_connect(argv[1], argv[2]);
9 Write(sockfd, "123", 3);
10 printf("wrote 3 bytes of normal datan");
11 sleep(1);
12 Send(sockfd, "4", 1, MSG_OOB);
13 printf("wrote 1 byte of OOB datan");
14 sleep(1);
15 Write(sockfd, "56", 2);
16 printf("wrote 2 bytes of normal datan");
17 sleep(1);
18 Send(sockfd, "7", 1, MSG_OOB);
19 printf("wrote 1 byte of OOB datan");