Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

После выполнения этой программы мы получаем следующий результат:

freebsd4 % tcprecv04 6666

read 3 bytes: 123

at OOB mark

read 2 bytes: 45

received EOF

Хотя принимающий TCP получил все посланные данные, первый вызов функции

read
возвращает только три байта, так как была обнаружена отметка внеполосных данных. Следующий считанный байт — это байт, содержащий внеполосные данные (его значение равно 4), так как мы дали ядру указание поместить внеполосные данные вместе с обычными.

Пример: дополнительные свойства внеполосных данных

Теперь мы покажем другой столь же простой пример, иллюстрирующий две дополнительные особенности внеполосных данных, о которых мы уже упоминали ранее.

1. TCP посылает уведомление об отправке внеполосных данных (их срочный указатель), даже если поток данных остановлен функциями управления потоком.

2. Принимающий процесс может получить уведомление о том, что отправитель отослал внеполосные данные (с помощью сигнала

SIGURG
или функции
select
) до того, как эти данные фактически прибудут. Если после получения этого уведомления процесс вызывает функцию
recv
, задавая флаг
MSG_OOB
, а внеполосные данные еще не прибыли, то будет возвращена ошибка
EWOULDBLOCK
.

В листинге 24.8 приведена программа отправки.

Листинг 24.8. Программа отправки

//oob/tcpsend05.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int sockfd, size;

6 char buff[16384];

7 if (argc != 3)

8 err_quit("usage: tcpsend04 <host> <port#>");

9 sockfd = Tcp_connect(argv[1], argv[2]);

10 size = 32768;

11 Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));

12 Write(sockfd, buff, 16384);

13 printf("wrote 16384 bytes of normal data\n");

14 sleep(5);

15 Send(sockfd, "a", 1, MSG_OOB);

16 printf("wrote 1 byte of OOB data\n");

17 Write(sockfd, buff, 1024);

18 printf("wrote 1024 bytes of normal data\n");

19 exit(0);

20 }

9-19
Этот процесс устанавливает размер буфера отправки сокета равным 32 768 байт, записывает 16 384 байт обычных данных, а затем на 5 с переходит в спящее состояние. Чуть ниже мы увидим, что приемник устанавливает размер приемного буфера сокета равным 4096 байт, поэтому данные, отправленные отсылающим TCP, с гарантией заполнят приемный буфер сокета получателя. Затем отправитель посылает один байт внеполосных данных, за которым следуют 1024 байт обычных данных, и, наконец, закрывает соединение.

В листинге 24.9 представлена принимающая программа.

Листинг 24.9. Принимающая программа

//oob/tcprecv05.c

1 #include "unp.h"

2 int listenfd, connfd;

3 void sig_urg(int);

4 int

5 main(int argc, char **argv)

6 {

7 int size;

8 if (argc == 2)

9 listenfd = Tcp_listen(NULL, argv[1], NULL);

10 else if (argc == 3)

11 listenfd = Tcp_listen(argv[1], argv[2], NULL);

12 else

13 err_quit("usage: tcprecv05 [ <host> ] <port#>");

14 size = 4096;

15 Setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));

16 connfd = Accept(listenfd, NULL, NULL);

17 Signal(SIGURG, sig_urg);

18 Fcntl(connfd, F_SETOWN, getpid);

19 for (;;)

20 pause;

21 }

22 void

23 sig_urg(int signo)

24 {

25 int n;

  • Читать дальше
  • 1
  • ...
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: