Литмир - Электронная Библиотека
ЛитМир: бестселлеры месяца
Содержание  
A
A

solaris % <b>grep 'Protocol not supported' /usr/include/sys/errno.h</b>

#define EPROTONOSUPPORT 120 /* Protocol not supported */

Это значение

errno
возвращается функцией
socket
. Далее смотрим в руководство пользователя:

solaris % <b>man socket</b>

В большинстве руководств пользователя в конце под заголовком «Errors» приводится дополнительная, хотя и лаконичная информация об ошибках.

1.4. Заменяем первое описание на следующее:

int sockfd, n, counter = 0;

Добавляем оператор

counter++;

в качестве первого оператора цикла

while
. Наконец, прежде чем прервать программу, выполняем

printf(&quot;counter = %d\n&quot;, counter);

На экран всегда выводится значение 1.

1.5. Объявим переменную i типа int и заменим вызов функции

write
на следующий:

for (i = 0; i &lt; strlen(buff); i++)

 Write(connfd, &amp;buff[i], 1);

Результат зависит от расположения клиентского узла и узла сервера. Если клиент и сервер находятся на одном узле, счетчик обычно равен 1. Это значит, что даже если сервер выполнит функцию

write
26 раз, данные будут возвращены за одну операцию считывания (
read
). Но если клиент запущен в Solaris 2.5.1, а сервер в BSD/OS 3.0, счетчик обычно равен 2. Просмотрев пакеты Ethernet, мы увидим, что первый символ отправляется в первом пакете сам по себе, а следующий пакет содержит остальные 25 символов. (Обсуждение алгоритма Нагла в разделе 7.9 объясняет причину такого поведения.)

Цель этого примера — продемонстрировать, что разные реализации TCP по-разному поступают с данными, поэтому наше приложение должно быть готово считывать данные как поток байтов, пока не будет достигнут конец потока.

Глава 2

2.1 Зайдите на веб-страницу

http://www.iana.org/numbers.htm
и найдите журнал под названием «IP Version Number». Номер версии 0 зарезервирован, версии 1-3 не использовались, а версия 5 представляет собой потоковый протокол Интернета (Internet Stream Protocol).

2.2. Все RFC бесплатно доступны по электронной почте, через FTP или Web. Стартовая страница для поиска находится по адресу

http://www.ietf.org
. Одним из мест расположения RFC является каталог
ftp://ftp.isi.edu/in-notes
. Для начала следует получить файл с текущим каталогом RFC, обычно это файл
rfc-index.txt
. HTML-версия хранится в файле
http://www.rfc-editor.org/rfc-index.html
. Если с помощью какого-либо редактора осуществить поиск термина «stream» (поток) в указателе RFC, мы выясним, что RFC 1819 определяет версию 2 потокового протокола Интернета. Какую бы информацию, которая может содержаться в RFC, мы ни искали, для поиска следует использовать указатель (каталог) RFC.

2.3. В версии IPv4 при таком значении MSS генерируется 576-байтовая дейтаграмма (20 байт для заголовка IPv4 и 20 байт для заголовка TCP). Это минимальный размер буфера для сборки фрагментов в Ipv4.

2.4. В данном примере сервер (а не клиент) осуществляет активное закрытие.

2.5. Узел в сети Token Ring не может посылать пакет, содержащий больше, чем 1460 байт данных, поскольку полученное им значение MSS равно 1460. Узел в сети Ethernet может посылать пакет размером до 4096 байт данных, но не превышающий величину MTU исходящего интерфейса (Ethernet) во избежание фрагментации. Протокол TCP не может превысить величину MSS, объявленную другой стороной, но он всегда может посылать пакеты меньшего размера.

2.6. В разделе «Protocol Numbers» (номера протоколов) RFC «Assigned Numbers» («Присвоенные номера») указано значение 89 для протокола OSPF.

2.7. Выборочное уведомление указывает лишь на получение пакетов с конкретными последовательными номерами. Кумулятивное уведомление сообщает о получении данных вплоть до конкретного порядкового номера (включительно). При освобождении буфера отправки в соответствии с выборочным уведомлением система может удалять только те данные, доставка которых была подтверждена явно, но не те, номера которых меньше или больше подтвержденных.

Глава 3

3.1. В языке С функция не может изменить значение аргумента, передаваемого по значению. Чтобы вызванная функция изменила значение, передаваемое вызывающим процессом, требуется, чтобы вызывающий процесс передал указатель на значение, подлежащее изменению.

3.2. Указатель должен увеличиваться на количество считанных или записанных байтов, но в языке С нет возможности увеличивать указатели типа

void
(поскольку компилятору не известно, на какой тип данных указывает указатель).

Глава 4

4.1. Посмотрите на определение констант, начинающихся с

INADDR_
, кроме
INADDR_ANY
(состоит из нулевых битов) и
INADDR_NONE
(состоит из единичных битов). Например, адрес многоадресной передачи класса D
INADDR_MAX_LOCAL_GROUP
определяется как
0xe00000ff
с комментарием «224.0.0.255», что явно указывает на порядок байтов узла.

4.2. Приведем новые строки, добавленные после вызова

connect
:

len = sizeof(cliaddr);

Getsockname(sockfd, (SA*)&amp;cliaddr, &amp;len);

printf(&quot;local addr: %s\n&quot;,

Sock_ntop((SA*)&amp;cliaddr, len));

Это требует описания переменной

len
как
socklen_t
, a
cliaddr
как структуры
struct sockaddr_in
. Обратите внимание, что аргумент типа «значение-результат» для функции
getsockname(len)
должен быть до вызова функции инициализирован размером переменной, на которую указывает второй аргумент. Наиболее частая ошибка программирования при использовании аргументов типа «значение-результат» заключается в том, что про эту инициализацию забывают.

4.3. Когда дочерний процесс вызывает функцию

close
, счетчик ссылок уменьшается с 2 до 1, так что клиенту не посылается сегмент FIN. Позже, когда родительский процесс вызывает функцию
close
, счетчик ссылок уменьшается до нуля, и тогда сегмент FIN посылается.

4.4. Функция

accept
возвращает значение
EINVAL
, так как первый аргумент не является прослушиваемым сокетом.

4.5. Вызов функции

listen
без вызова функции
bind
присваивает прослушиваемому сокету динамически назначаемый порт.

Глава 5

5.1. Длительность состояния TIME_WAIT должна находиться в интервале между 1 и 4 минутами, что дает величину MSL от 30 с до 2 мин.

382
{"b":"225366","o":1}
ЛитМир: бестселлеры месяца