UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
23 n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);
24 buff[n] = 0; /* завершающий нуль */
25 printf("read %d OOB byte: %sn", n, buff);
26 justreadoob = 1;
27 FD_CLR(connfd, &xset);
28 }
29 if (FD_ISSET(connfd, &rset)) {
30 if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {
31 printf("received EOFn");
32 exit(0);
33 }
34 buff[n] = 0; /* завершающий нуль */
35 printf("read %d bytes: %sn", n, buff);
36 justreadoob = 0;
37 }
38 }
39 }
5
justreadoob
select
26-27
justreadoob
Теперь программа работает так, как мы ожидали.
24.3. Функция sockatmark
С приемом внеполосных данных всегда связана так называемая отметка внеполосных данных (out-of-bandmark). Это позиция в потоке обычных данных на стороне отправителя, соответствующая тому моменту; когда посылающий процесс отправляет байт, содержащий внеполосные данные. Считывая данные из сокета, принимающий процесс путем вызова функции
sockatmark
#include <sys/socket.h>
int sockatmark(int <i>sockfd</i>);
<i>Возвращает: 1, если находится на отметке внеполосных данных: 0, если не на отметке; -1 в случае ошибки</i>
Эта функция появилась в POSIX. Разработчики стандарта POSIX стремятся заменить отдельными функциями все вызовы ioctl с различными параметрами.
В листинге 24.5 показана реализация этой функции с помощью поддерживаемого в большинстве систем параметра
SIOCATMARK
ioctl
Листинг 24.5. Функция sockatmark реализована с использованием функции ioctl
//lib/sockatmark.c
1 #include "unp.h"
2 int
3 sockatmark(int fd)
4 {
5 int flag;
6 if (ioctl(fd, SIOCATMARK, &flag) < 0)
7 return (-1);
8 return (flag != 0 ? 1 : 0);
9 }
Отметка внеполосных данных применима независимо от того, как принимающий процесс получает внеполосные данные: вместе с обычными данными (параметр сокета
SO_OOBINLINE
MSG_OOB
Пример: особенности отметки внеполосных данных
Далее мы приводим простой пример, иллюстрирующий следующие две особенности отметки внеполосных данных:
1. Отметка внеполосных данных всегда указывает на один байт дальше конечного байта обычных данных. Это означает, что, когда внеполосные данные получены вместе с обычными, функция
sockatmark
MSG_OOB
SO_OOBINLINE
sockatmark
2. Операция считывания всегда останавливается на отметке внеполосных данных [128, с. 519–520]. Это означает, что если в приемном буфере сокета 100 байт, но только 5 из них расположены перед отметкой внеполосных данных, то когда процесс выполнит функцию
read
sockatmark
В листинге 24.6 показана наша программа отправки. Она посылает три байта обычных данных, один байт внеполосных данных, а затем еще один байт обычных данных. Паузы между этими операциями отсутствуют.
В листинге 24.7 показана принимающая программа. В ней не используется ни функция
select
SIGURG
sokatmark
Листинг 24.6. Программа отправки
//oob/tcpsen04.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: tcpsend04 <host> <port#>");
8 sockfd = Tcp_connect(argv[1], argv[2]);
9 Write(sockfd, "123", 3);
10 printf("wrote 3 bytes of normal datan");
11 Send(sockfd, "4", 1, MSG_OOB);
12 printf("wrote 1 byte of OOB datan");