Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Эффективное программирование TCP/IP

Покупка
Артикул: 616177.01.99
Программирование TCP/IP может показаться очень простым, но это заблуждение. Многие программисты сталкиваются с тем, что написанное ими сетевое приложение недостаточно надежно. Особое внимание в данной книге уделено тонким вопросам функционирования семейства протоколов и способам работы с ними. Здесь изложены подтвержденные практикой советы, технические приемы и эвристические правила программирования TCP/IP для достижения максимальной производительности; показано, как избежать многих типичных ошибок. Основные идеи и концепции иллюстрируются многочисленными примерами. Книга значительно ускорит процесс обучения программированию и позволит вам быстро достичь уровня профессионала.
Cнейдер, Й. Снейдер, Й. Эффективное программирование TCP/IP / Йон Снейдер; пер. с англ. А.А. Слинкина. - Москва : ДМК Пресс. - 320 с. - (Для программистов). - ISBN 978-5-94074-670-6. - Текст : электронный. - URL: https://znanium.com/catalog/product/409174 (дата обращения: 20.04.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов. Для полноценной работы с документом, пожалуйста, перейдите в ридер.
Эффективное программирование TCP/IP

Йон Снейдер

Effective TCP/IP
Programming
44 Tips
to Improve Your
Network Programs

Jon C. Snader

Boston • San Francisco • New York • Toronto • Montreal

London • Munich • Paris • Madrid
Capetown • Sidney • Tokyo • Singapore • Mexico City

Эффективное

программирование

TCP/IP

Йон Снейдер

Москва

Серия «Для программистов»

ББК 32.973.202018.2

С53

Cнейдер Й.

С53 Эффективное программирование TCP/IP: Пер. с англ. – М.: ДМК Пресс.

– 320 с.: ил. (Серия «Для программистов»).

ISBN 97859407470Программирование TCP/IP может показаться очень простым, но это

заблуждение. Многие программисты сталкиваются с тем, что написанное
ими сетевое приложение недостаточно надежно. Особое внимание в данной
книге уделено тонким вопросам функционирования семейства протоколов
и способам работы с ними. Здесь изложены подтвержденные практикой
советы, технические приемы и эвристические правила программирования
TCP/IP для достижения максимальной производительности; показано, как
избежать многих типичных ошибок. Основные идеи и концепции иллюстрируются многочисленными примерами.

Книга значительно ускорит процесс обучения программированию и позволит вам быстро достичь уровня профессионала.

ББК 32.973.202018.2

Публикуется по согласованию с издательством, выпустившим оригинал: ADDISONWESLEY LONGMAN, a Pearson Education Company.

Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы

то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев
авторских прав.

Материал, изложенный в данной книге, многократно проверен. Но, поскольку вероятность

технических ошибок все равно существует, издательство не может гарантировать абсолютную
точность и правильность приводимых сведений. В связи с этим издательство не несет ответственности за возможные ошибки, связанные с использованием книги.

ISBN 0201615894 (англ.)
Translation copyright – by DMK Press
(Effective TCP/IP Programming:
44 Tips to Improve Your Network Programs,
First Edition by Jon Snader,
Copyright © All Rights Reserved)

ДМК Пресс

6 
6 

ISBN 978594074706 
6 
                 (рус.)        Перевод на русский язык, оформление.
©

Содержание

Предисловие ................................................................................... 11
Глава 1. Введение ........................................................................ 15
Некоторые термины ........................................................................ 15
Путеводитель по книге .................................................................... 16
Архитектура клиентсервер ............................................................ 18
Элементы API сокетов ..................................................................... 20
Резюме ............................................................................................ 28
Глава 2. Основы ............................................................................. 29
Совет 1. О необходимости различать протоколы,
требующие и не требующие
установления логического соединения ............................... 29
Резюме ............................................................................................ 35
Совет 2. О том, что такое подсети и CIDR .......................................... 35
Классы адресов ................................................................................. 36
Подсети ............................................................................................ 40
Ограниченное вещание ................................................................... 43
Вещание на сеть .............................................................................. 44
Вещание на подсеть ........................................................................ 44
Вещание на все подсети ................................................................. 44
Бесклассовая междоменная маршрутизация – CIDR .................. 45
Текущее состояние организации подсетей и CIDR ...................... 47
Резюме ............................................................................................ 47
Совет 3. О том, что такое частные адреса и NAT ................................ 48
Резюме ............................................................................................ 50
Совет 4. О разработке и применении каркасов приложений ............. 50
Каркас TCPсервера .......................................................................... 52
Каркас TCPклиента ........................................................................... 57
Каркас UDPсервера .......................................................................... 59
Каркас UDPклиента ........................................................................... 61
Резюме ............................................................................................ 63

Эффективное программирование TCP/IP

Совет 5. О том, почему интерфейс сокетов
лучше интерфейса XTI/TLI ................................................... 63
Резюме ............................................................................................ 65
Совет 6. О том, что TCP – потоковый протокол ................................. 65
Резюме ............................................................................................ 73
Совет 7. О важности правильной оценки производительности TCP ....... 73
Источник и приемник на базе UDP ........................................................ 75
Источник и приемник на базе TCP ........................................................ 77
Резюме ............................................................................................ 84
Совет 8. О том, что не надо заново изобретать TCP .......................... 84
Резюме ............................................................................................ 87
Совет 9. О том, что при всей надежности у TCP есть и недостатки .... 87
Что такое надежность ......................................................................... 87
Потенциальные ошибки ...................................................................... 89
Сбой в сети ....................................................................................... 90
Отказ приложения ............................................................................. 90
Крах хоста на другом конце соединения ............................................... 95
Резюме ............................................................................................ 96
Совет 10. О том, что TCP не выполняет опрос соединения ................ 96
Механизм контролеров ...................................................................... 97
Пульсация ........................................................................................ 99
Еще один пример пульсации ............................................................. 104
Резюме .......................................................................................... 110
Совет 11. О некорректном поведении партнера ............................. 111
Проверка завершения работы клиента ............................................... 112
Проверка корректности входной информации ..................................... 114
Резюме .......................................................................................... 118
Совет 12. О работе программы в локальной и глобальной сетях ..... 118
Недостаточная производительность .................................................. 119
Скрытая ошибка .............................................................................. 120
Резюме .......................................................................................... 124
Совет 13. О функционировании протоколов .................................... 124
Резюме .......................................................................................... 125
Совет 14. О семиуровневой эталонной модели OSI ........................ 126
Модель OSI ..................................................................................... 126
Модель TCP/IP ................................................................................ 128
Резюме .......................................................................................... 130

Содержание

Глава 3.  Создание эффективных
и устойчивых сетевых программ ................... 131
Совет 15. Об операции записи в TCP .............................................. 131
Операция записи с точки зрения приложения ...................................... 131
Операция записи с точки зрения TCP ................................................. 132
Резюме .......................................................................................... 136
Совет 16. О важности аккуратного размыкания
TCPсоединений ............................................................. 137
Вызов shutdown ............................................................................... 137
Аккуратное размыкание соединений .................................................. 139
Резюме .......................................................................................... 144
Совет 17. О запуске приложения через inetd ................................... 144
TCPсерверы .................................................................................. 145
UDPсерверы .................................................................................. 149
Резюме .......................................................................................... 154
Совет 18. О назначении серверу номера порта
с помощью tcpmux .......................................................... 154
Резюме .....................................................................................................163
Совет 19. Об использовании двух TCPсоединений ........................ 163
Архитектура с одним соединением .................................................... 164
Архитектура с двумя соединениями ................................................... 165
Резюме .......................................................................................... 170
Совет 20. О том, как сделать приложение
событийноуправляемым (1) ........................................... 170
Резюме .......................................................................................... 179
Совет 21. О том, как сделать приложение
событийноуправляемым (2) ........................................... 179
Резюме .......................................................................................... 187
Совет 22. О том, что не надо прерывать состояние TIMEWAIT
для закрытия соединения ................................................ 187
Что это такое ................................................................................... 188
Зачем нужно состояние TIMEWAIT ..................................................... 189
Принудительная отмена состояния TIMEWAIT ..................................... 190
Резюме .......................................................................................... 192
Совет 23. Об установке опции SO_REUSEADDR .............................. 192
Резюме .......................................................................................... 197

Эффективное программирование TCP/IP

Совет 24. О написании одного большого блока
вместо нескольких маленьких ......................................... 197
Отключение алгоритма Нейгла .......................................................... 200
Запись со сбором ............................................................................ 201
Резюме .......................................................................................... 204
Совет 25. Об организации таймаута для вызова connect ............... 204
Использование вызова alarm ............................................................. 205
Использование select ............................................................................... 207
Резюме .......................................................................................... 210
Совет 26. О вреде копирования данных .......................................... 210
Буферы в разделяемой памяти .......................................................... 212
Система буферов в разделяемой памяти ............................................ 213
Реализация в UNIX ........................................................................... 216
Реализация в Windows ...................................................................... 220
Резюме .......................................................................................... 224
Совет 27. Об обнулении структуры sockaddr_in ............................... 225
Совет 28. О важности порядка байтов ............................................. 225
Резюме .......................................................................................... 228
Совет 29. О том, что не стоит «зашивать» IPадреса
и номера портов в код ..................................................... 229
Резюме .......................................................................................... 234
Совет 30. О подсоединенном UDPсокете ...................................... 234
Резюме .......................................................................................... 238
Совет 31. О том, что C – не единственный
язык программирования ................................................. 238
Резюме .......................................................................................... 243
Совет 32. О значимости размеров буферов .................................... 243
Резюме .......................................................................................... 247

Глава 4. Инструменты и ресурсы ....................................... 248
Совет 33. Об использовании утилиты ping ...................................... 248
Резюме .......................................................................................... 251
Совет 34. Об использовании программы tcpdump
или аналогичного средства ............................................. 251
Как работает tcpdump ...................................................................... 251
Использование tcpdump ................................................................... 255
Выходная информация, формируемая tcpdump ................................... 256
Резюме .......................................................................................... 261

Содержание

Совет 35. О применении программы traceroute ............................... 261
Как работает traceroute .................................................................... 262
Программа tracert в системе Windows ................................................. 266
Резюме .......................................................................................... 267
Совет 36. О преимуществах программы ttcp ................................... 267
Резюме .......................................................................................... 271
Совет 37. О работе с программой lsof ............................................. 271
Резюме .......................................................................................... 273
Совет 38. Об использовании программы netstat ............................. 273
Активные сокеты .............................................................................. 273
Интерфейсы ................................................................................... 275
Маршрутная таблица ....................................................................... 276
Статистика протоколов ..................................................................... 279
Программа netstat в Windows ............................................................ 281
Резюме .................................................................................................... 281
Совет 39. О средствах трассировки системных вызовов ................ 281
Преждевременное завершение ......................................................... 282
Низкая производительность ttcp ........................................................ 286
Резюме .......................................................................................... 287
Совет 40. О создании и применении программы
для анализа ICMPсообщений ......................................... 287
Чтение ICMPсообщений .................................................................. 288
Печать ICMPсообщений .................................................................. 289
Резюме .......................................................................................... 295
Совет 41. О пользе книг Стивенса ................................................... 295
«TCP/IP Illustrated» ........................................................................... 295
«UNIX Network Programming» ............................................................. 297
Совет 42. О чтении текстов программ ............................................. 297
Резюме .......................................................................................... 299
Совет 43. О том, что надо знать RFC ............................................... 299
Тексты RFC ..................................................................................... 300
Совет 44. Об участии в конференциях Usenet .................................. 300
Другие ресурсы, относящиеся к конференциям ................................... 301
Приложение 1 ............................................................................... 303
Вспомогательный код для UNIX .................................................... 303
Заголовочный файл etcp.h ................................................................ 303

Эффективное программирование TCP/IP

Функция daemon .............................................................................. 304
Функция signal ..........................................................................................305
Приложение 2 ............................................................................... 307
Вспомогательный код для Windows ............................................. 307
Заголовочный файл skel.h ................................................................. 307
Функции совместимости с Windows ............................................ 307
Литература ..................................................................................... 310
Предметный указатель ........................................................... 314

Посвящается Марии

Предисловие

В результате взрывного развития Internet, беспроводных видов связи и сетей соразмерно увеличилось число программистов и инженеров, занимающихся разработкой сетевых приложений. Программирование TCP/IP может показаться обманчиво простым. Интерфейс прикладного программирования (API) несложен.
Даже новичок может взять шаблон клиента или сервера и создать на его основе
работающее приложение.
К сожалению, нередко после весьма продуктивного начала неофиты начинают
понимать, что все не так очевидно, а созданная ими программа оказывается и медленной, и нестабильной. В сетевом программировании есть множество «темных
уголков» и трудно понимаемых деталей. Цель этой книги – ответить на возникающие вопросы и помочь разобраться с тонкостями программирования TCP/IP.
Прочитав данную книгу, вы научитесь преодолевать трудности сетевого программирования. Здесь будут рассмотрены многие вопросы, на первый взгляд, лишь
отдаленно связанные с теми знаниями, которыми должен обладать программист
сетевых приложений. Но без понимания таких деталей не разобраться в том, как
сетевые протоколы взаимодействуют с приложением. Ранее казавшееся загадочным «поведение» приложения при ближайшем рассмотрении становится совершенно понятным, решение проблемы лежит на поверхности.
Книга построена несколько необычно. Типичные проблемы представлены в виде
серии советов. Разбираясь с конкретным вопросом, вы будете переходить к изучению того или иного аспекта TCP/IP. К концу главы вы не только решите частную
задачу, но и углубите понимание того, как работают и взаимодействуют с приложением протоколы TCP/IP.
Разбивка книги на отдельные советы в какойто мере лишает текст логической
последовательности. Чтобы помочь вам сориентироваться, в главу 1 помещен путеводитель, описывающий расположение материала. Получить общее представление об организации книги поможет также оглавление, в котором перечислены все
советы. Поскольку каждый совет дан в повелительном наклонении, оглавление
можно считать списком рецептов.
С другой стороны, такая организация материала позволяет использовать книгу в качестве справочника. Столкнувшись в повседневной работе с какойлибо
проблемой, вы можете обратиться к соответствующему совету, чтобы вспомнить

Предисловие

ее решение. Многие темы затрагиваются в нескольких советах, иногда под разным углом зрения. Такое повторение помогает усвоению сложных концепций,
проясняя мотивы тех или иных решений.

Аудитория

Данная книга предназначена, главным образом, начинающим и программистам
среднего уровня, но даже опытные специалисты найдут в ней много полезного для
себя. Хотя и предполагается, что читатель знаком с сетями и основами API на базе
сокетов, в главе 1 приводится обзор элементарных вызовов API и их использования
для создания примитивного клиента и сервера. В совете 4 более детально рассмотрены модели клиента и сервера, поэтому даже читатель с минимальной подготовкой
сможет извлечь из представленного материала практическую пользу.
Почти все примеры написаны на языке C, безусловно, необходимы базовые
навыки программирования на этом языке для понимания приведенных в книге
программ. В совете 31 представлены некоторые примеры на языке Perl. Но, впрочем, предварительное знание Perl необязательно. Здесь встречаются и небольшие
примеры на языках командных интерпретаторов (shell), но и для их понимания
знакомства с shellпрограммированием не нужно.
Материал для изучения подан по возможности максимально независимо от
платформы. За немногими исключениями, приводимые в примерах программы
должны компилироваться и работать на любой платформе UNIX или Win32. Но
программисты, которые используют системы, отличные от UNIX и Windows, тоже
могут без особых трудностей применять примеры на своей платформе.

Принятые в книге соглашения

По ходу изложения приведены небольшие программы для иллюстрации различных аспектов исследуемой проблемы. Здесь будут использоваться следующие
соглашения:

текст, который набирает пользователь, печатается полужирным моноширинным шрифтом;

текст, который выводят системы, печатается обычным моноширинным
шрифтом;

комментарии, не являющиеся частью ввода или вывода, печатаются курсивным моноширинным шрифтом.

Пример из совета 9:

bsd: $ tcprw localhost 9000
hello
получено сообщение 1
печатается после пятисекундной задержки
здесь сервер остановили
hello again
tcprw: ошибка вызова readline: Connection reset by peer (54)
bsd: $

#include <sys/socket.h>
/* UNIX */
#include <winsock2.h>
/* Windows */

int connect( SOCKET s, const struct sockaddr *peer, int peer_len );

Возвращаемое значение: 0 – нормально, –1 (UNIX) или не 0 (Windows) –
ошибка.

#include "etcp.h"

SOCKET tcp_server( char *host, char *port );

Возвращаемое значение: сокет в режиме прослушивания (в случае ошибки завершает программу).

* Речь идет о трехтомном издании «TCP\IP Illustrated» и двухтомном «UNIX Network Programming». – Прим. перев.

Обратите внимание на приглашение командного интерпретатора, содержащее
имя системы. Предыдущий пример исполнялся на машине с именем bsd.
В рамке дается описание вводимой в рассмотрение новой функции API – собственной или системного вызова. Стандартные системные вызовы обводятся
сплошной рамкой:

Оформление

Примечание
Таким образом отмечены попутные замечания и дополнительный материал. При первом чтении подобный материал можно
пропускать.

Наконец, URL подчеркивается:

http://www.freebsd.org.

Исходные тексты и список исправлений

Исходные тексты всех встречающихся в книге примеров представлены на сайте издательства «ДМКПресс» http://www.dmk.ru. Вы можете загрузить их на свой
компьютер и поэкспериментировать. На этом сайте находятся каркасы программ
и код библиотечных функций.

Оформление

Мне очень нравится оформление книг Ричарда Стивенса*. Приступая к работе
над этой книгой, я попросил у Рича разрешения скопировать его стиль. Рич со
свойственным ему великодушием не только не возражал, но даже посодействовал
этой «краже», прислав мне макросы для форматера GROFF, которыми он пользовался при наборе своих книг.
Если вам понравится это издание, то благодарить следует Рича. В противном
случае загляните в любую из его книг, чтобы понять, к чему я стремился.

Разработанные автором функции обведены пунктирной рамкой:

Предисловие

Благодарности

Традиционно авторы книг благодарят свои семьи за поддержку во время работы над книгой, и теперь я знаю, почему. Эта работа не была бы закончена, если
бы не помощь моей жены Марии. И эти слова – лишь жалкая попытка воздать ей
должное за дополнительные хлопоты и одинокие вечера.
Также ценнейшую поддержку оказали рецензенты. В ранних вариантах рукописи они нашли многочисленные ошибки, как технические, так и типографские,
разъяснили то, что я неправильно понимал или не знал, предложили свежий подход. Хочется выразить благодарность Крису Клиланду (Chris Cleeland), Бобу Джиллигену (Bob Gilligan, FreeGate Corp.), Питеру Хэверлоку (Peter Haverlock, Nortel
Networks), С. Ли Генри (S. Lee Henry, Web Publishing, Inc.), Мукешу Кэкеру
(Mukesh Kacker, Sun Microsystems, Inc.), Барри Марголину (Barry Margolin, GTE
Internetworking), Майку Оливеру (Mike Oliver, Sun Microsystems, Inc.), Юри Рацу
(Uri Raz) и Ричу Стивенсу (Rich Stevens).
Необходимо поблагодарить редактора Карен Геттман (Karen Gettman), ведущего редактора Мэри Гарт (Mary Hart), координатора проекта Тиреллу Элбо (Tyrrell
Albaugh) и корректора Кэт Охала (Cat Ohala). Мне было приятно с ними работать, они очень помогли начинающему автору.
Я приветствую любые замечания и предложения читателей. Пишите мне по
электронному адресу, указанному ниже.

Йон Снейдер
Тампа, Флорида
jsnader@ix.netcom.com
Декабрь, 1999
http://www.netcom.com/~jsnader

Глава 1. Введение

Цель этой книги – помочь программистам разных уровней – от начального до
среднего – повысить свою квалификацию. Для получения статуса мастера требуется практический опыт и накопление знаний в конкретной области. Конечно,
опыт приходит только со временем и практикой, но данная книга существенно
пополнит багаж ваших знаний.
Сетевое программирование – это обширная область с большим выбором различных технологий для желающих установить связь между несколькими машинами. Среди них такие простые, как последовательная линия связи, и такие сложные,
как системная сетевая архитектура (SNA) компании IBM. Но сегодня протоколы
TCP/IP – наиболее перспективная технология построения сетей. Это обусловлено
развитием Internet и самого распространенного приложения – Всемирной паутины (World Wide Web).

Примечание
Вообщето, Web – не приложение. Но это и не протокол, хотя
в ней используются и приложения (Webбраузеры и серверы),
и протоколы (например, HTTP). Web – это самое популярное среди пользователей Internet применение сетевых технологий.

Однако и до появления Web TCP/IP был распространенным методом создания сетей. Это открытый стандарт, и на его основе можно объединять машины разных производителей. К концу 90х годов TCP/IP завоевал лидирующее положение среди сетевых технологий, видимо, оно сохранится и в дальнейшем. По этой
причине в книге рассматриваются TCP/IP и сети, в которых он работает.
При желании совершенствоваться в сетевом программировании необходимо
сначала овладеть некоторыми основами, чтобы в полной мере оценить, чем же вам
предстоит заниматься. Рассмотрим несколько типичных проблем, с которыми сталкиваются начинающие. Многие из этих проблем – результат частичного или полного непонимания некоторых аспектов протоколов TCP/IP и тех API, с помощью
которых программа использует эти протоколы. Такие проблемы возникают в реальной жизни и порождают многочисленные вопросы в сетевых конференциях.

Некоторые термины

За немногими исключениями, весь материал этой книги, в том числе примеры
программ, предложен для работы в системах UNIX (32 и 64разрядных) и системах, использующих API Microsoft Windows (Win32 API). Я не экспериментировал
с 16разрядными приложениями Windows. Но и для других платформ почти все
остается применимым.

Введение

Желание сохранить переносимость привело к некоторым несообразностям
в примерах программ. Так, программисты, работающие на платформе UNIX, неодобрительно отнесутся к тому, что для дескрипторов сокетов применяется тип SOCKET
вместо привычного int. А программисты Windows заметят, что я ограничился только консольными приложениями. Все принятые соглашения описаны в совете 4.
По той же причине я обычно избегаю системных вызовов read и write для
сокетов, так как Win32 API их не поддерживает. Для чтения из сокета или записи
в него применяются системные вызовы recv, recvfrom или recvmsg для чтения
и send, sendto или sendmsg для записи.
Одним из самых трудных был вопрос о том, следует ли включать в книгу материал по протоколу IPv6, который в скором времени должен заменить современную версию протокола IP (IPv4). В конце концов, было решено не делать этого.
Тому есть много причин, в том числе:

почти все изложенное в книге справедливо как для IPv4, так и для IPv6;

различия, которые всетаки имеются, по большей части сосредоточены в тех
частях API, которые связаны с адресацией;

книга представляет собой квинтэссенцию опыта и знаний современных сетевых программистов, а реального опыта работы с протоколом IPv6 еще не
накоплено.

Поэтому, если речь идет просто об IP, то подразумевается IPv4. Там, где упоминается об IPv6, об этом написано.
И, наконец, я называю восемь бит информации байтом. В сетевом сообществе
принято называть такую единицу октетом – по историческим причинам. Когдато
размер байта зависел от платформы, и не было единого мнения о его точной длине.
Чтобы избежать неоднозначности, в ранней литературе по сетям и был придуман
термин октет. Но сегодня все согласны с тем, что длина байта равна восьми битам
[Kernighan and Pike 1999], так что употребление этого термина можно считать излишним педантизмом.

Примечание
Однако утверждения о том, что длина байта равна восьми битам,
время от времени все же вызывают споры в конференциях Usenet:
«Ох уж эта нынешняя молодежь! Я в свое время работал на машине Баста6, в которой байт был равен пяти с половиной битам.
Так что не рассказывайте мне, что в байте всегда восемь бит».

Путеводитель по книге

Ниже будут рассмотрены основы API сокетов и архитектура клиентсервер,
свойственная приложениям, в которых используется TCP/IP. Это тот фундамент,
на котором вы станете возводить здание своего мастерства.
В главе 2 обсуждаются некоторые заблуждения по поводу TCP/IP и сетей вообще. В частности, вы узнаете, в чем разница между протоколами, требующими
логического соединения, и протоколами, не нуждающимися в нем. Здесь будет рассказано об IPадресации и подсетях (эта концепция часто вызывает недоумение),
о бесклассовой междоменной маршрутизации (Classless Interdomain Routing – CIDR)