51 /* Фатальная ошибка, не относящаяся к системному вызову.
52 Выводим сообщение и заканчиваем работу. */
53 void
54 err_quit(const char *fmt, ...)
55 {
56 va_list ap;
57 va_start(ap, fmt);
58 err_doit(0, LOG_ERR, fmt, ap);
59 va_end(ap);
60 exit(1);
61 }
62 /* Выводим сообщение и возвращаем управление.
63 Вызывающий процесс задает "errnoflag" и "level" */
64 static void
65 err_doit(int errnoflag, int level, const char *fmt, va_list ap)
66 {
67 int errno_save, n;
68 char buf[MAXLINE + 1];
69 errno_save = errno; /* значение может понадобиться вызвавшему
процессу */
70 #ifdef HAVE_VSNPRINTF
71 vsnprintf(buf, MAXLINE, fmt, ap); /* защищенный вариант */
72 #else
73 vsprintf(buf, fmt, ap); /* незащищенный вариант */
74 #endif
75 n = strlen(buf);
76 if (errnoflag)
77 snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
78 strcat(buf, "\n");
79 if (daemon_proc) {
80 syslog(level, buf);
81 } else {
82 fflush(stdout); /* если stdout и stderr совпадают */
83 fputs(buf, stderr);
84 fflush(stderr);
85 }
86 return;
87 }
Приложение Д
Решения некоторых упражнений
Глава 1
1.3. В операционной системе Solaris получаем:
solaris % daytimetcpcli 127.0.0.1
socket error: Protocol not supported
Для получения дополнительной информации об этой ошибке сначала используем программу grep
, чтобы найти строку Protocol not supported
в заголовочном файле
.
solaris % grep 'Protocol not supported' /usr/include/sys/errno.h
#define EPROTONOSUPPORT 120 /* Protocol not supported */
Это значение errno
возвращается функцией socket
. Далее смотрим в руководство пользователя:
solaris % man socket
В большинстве руководств пользователя в конце под заголовком «Errors» приводится дополнительная, хотя и лаконичная информация об ошибках.
1.4. Заменяем первое описание на следующее:
int sockfd, n, counter = 0;
Добавляем оператор
counter++;
в качестве первого оператора цикла while
. Наконец, прежде чем прервать программу, выполняем
printf("counter = %d\n", counter);
На экран всегда выводится значение 1.
1.5. Объявим переменную i типа int и заменим вызов функции write
на следующий:
for (i = 0; i < strlen(buff); i++)
Write(connfd, &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).
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии