Сидни Фейт - TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security)
- Название:TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security)
- Автор:
- Жанр:
- Издательство:Лори
- Год:2000
- Город:Москва
- ISBN:5-85582-072-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Сидни Фейт - TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) краткое содержание
Второе издание популярного справочника полностью переработано и расширено с целью предоставить читателю наиболее полное описание средств разработки, конфигурирования, использования и обслуживания сетей TCP/IP и соответствующих служб.
Книга написана увлекательно и доступно. Она содержит дополнительные материалы о нескольких протоколах Интернета, используемых серверами и браузерами WWW, а также рассматривает все последние изменения в этой области. В книгу включены главы о новом стандарте безопасности IP и протоколе IP следующего поколения, известном как IPng или IPv6. Рисунки и таблицы наглядно показывают влияние средств безопасности IP и IPng на существующие сетевые среды.
Издание содержит следующие дополнительные разделы:
• Безопасность IP и IPv6
• Описание средств WWW, новостей Интернета и приложений для работы с gopher
• Подробное описание серверов имен доменов (DNS), маски подсети и бесклассовой маршрутизации в Интернете
• Таблицы и протоколы маршрутизации
• Руководство по реализации средств безопасности для каждого из протоколов и приложений
• Примеры диалогов с новыми графическими инструментами
Новое издание бестселлера по TCP/IP станет незаменимым помощником для разработчиков сетей и приложений, для сетевых администраторов и конечных пользователей.
TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
возвращаемый_код = bind(дескриптор_socket, адресная_структура, длина_адресной_структуры)
Если адресная структура идентифицирует нужный порт, bind попытается получить его на сервере. Если переменная порта имеет значение 0, bind получит один из неиспользованных портов. Функция bind позволяет ввести номер порта и IP-адрес в TCB. Вызов getsockname имеет форму:
возвращаемый_код = getsockname(дескриптор_socket, адресная_структура, длина_адресной_структуры)
Мы запросили у bind выделение порта, но эта функция не сообщает нам, какой именно порт был предоставлен. Для выяснения этого нужно прочитать соответствующие данные из TCB. Функция getsockname () извлекает информацию из TCB и копирует ее в адресную структуру, где можно будет прочитать эти сведения. Номер порта извлекается и выводится следующим оператором:
printf("SERVER: Номер порта %d\n", ntohs(servAddr.sin_port))
;
Функция ntohs () имеет полное название network-to-host-short и служит для преобразования номера порта из порядка следования байт в сети в локальный порядок следования байт на хосте.
4. listen(sockMain, 5);
Вызов listen применяется для ориентированных на соединение серверов и имеет форму:
возвращаемый_код = listen(дескриптор_socket, размер_очереди)
Вызов listen указывает, что это будет пассивный socket, и создает очередь требуемого размера для хранения поступающих запросов на соединения.
5. sockClient = accept(sockMain, 0, 0);
Вызов accept имеет форму:
новым_дескриптор_socket = accept(дескриптор_socket,
клиентская_адресная_структура, длина_клиентской_адресной_структуры)
По умолчанию вызов блокируется до соединения клиента с сервером. Если указана переменная клиентская_адресная_структура , после соединения клиента в эту структуру будут введены IP-адрес и порт клиента. В этом примере программы не проверяются IP-адрес и номер порта клиента, а просто два последних поля параметра заполняются нулями.
6. child = fork();
…
close(sockMain);
В языке С команда fork создает новый дочерний процесс, который наследует все дескрипторы ввода/вывода родительской программы, а также имеет доступ к sockMain и sockClient . Операционная система отслеживает количество процессов, имеющих доступ к socket.
Соединение закрывается, когда последний обращающийся к socket процесс вызывает close (). Когда дочерний процесс закрывает sockMain, родительский процесс все еще имеет доступ к socket.
7. close(sockClient);
Этот вызов выполняется из родительской части программы. Когда родительский процесс закрывает sockClient, дочерний процесс все еще имеет доступ к socket.
8. msgLength = recv(sockClient, buf, BUFLEN, 0));
…
close(sockClient);
Вызов recv имеет форму:
длина_сообщения = recv(дескриптор_socket, буфер, длина_буфера, флаги)
По умолчанию вызов recv блокированный. Функции fcntl () или iocntl () позволяют изменить статус socket на неблокированный режим.
После получения данных дочерним процессом и вывода сообщения на печать, доступ к sockClient закрывается. Это заставит соединение перейти в фазу закрытия.
21.7 Клиентская программа TCP
Клиент соединяется с сервером, посылает одно сообщение, и далее работа программы завершается (фрагменты программы рассматриваются в следующем разделе). Для запуска программы конечный пользователь должен ввести имя хоста сервера, номер порта и сообщение, которое будет послано на этот сервер. Например:
tcpclient pltim.cs.yale.edu 1356 hello
/* tcpclient.с
* Перед запуском клиента должен быть запущен сервер. Производится
* поиск порта сервера. Для запуска клиента нужно ввести:
* tcpclient имя_хоста порт сообщение */
#include
#include
#include
#include
#include
#include
main(argc, argv) /* Клиентская программа имеет входные аргументы. */
int argc;
char* argv[];
{
int sock;
struct sockaddr_in servAddr;
struct hostent *hp, *gethostbyname();
/* Аргументами будут 0:имя_программы, 1:имя_хоста, 2:порт, 3:сообщение */
if (argc < 4)
{
printf("ВВЕСТИ tcpclient имя_хоста порт сообщение\n");
exit(1);
}
/* 1. Создание TCB. */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("He могу получить socket\n");
exit(1);
}
/* 2. Заполнить поля адреса и порта сервера в servAddr.
* Сначала заполнить нулями адресную структуру. Затем получить IP-адрес
* для данного имени хоста и ввести его в адресную структуру.
* Наконец ввести номер порта, взяв его из argv[2]. */
bzero((char *)&servAddr, sizeof(servAddr));
servAddr.sin_family = AF_INET;
hp = gethostbyname (argv[1]);
bcopy(hp->h_addr, &servAddr.sin_addr, hp->h_length);
servAddr.sin_port = htons(atoi(argv[2]));
/* 3. Соединиться с сервером. Вызывать bind не нужно.
* Система присвоит свободный порт во время выполнения соединения. */
if (connect (sock, &servAddr, sizeof(servAddr)) < 0) {
perror("Клиент не может соединиться.\n");
exit(1);
}
/* 4. Клиент анонсирует свою готовность послать сообщение.
* Сообщение отправляется, и распечатывается последняя строка. */
printf ("CLIENT: Готов к пересылке\n");
if (send(sock, argv[3], strlen(argv[3]), 0) < 0) {
(perror("Проблемы с пересылкой.\n");
exit(1);
}
printf ("CLIENT: Пересылка завершена. Счастливо оставаться.\n");
close(sock);
exit(0);
}
21.7.1 Вызовы в клиентской программе TCP
1. sock = socket(AF_INET, SOCK_STREAM, 0);
Клиент создает блок управления пересылкой ("socket") так же, как это делал сервер.
2. Сервер должен инициализировать адресную структуру для использования в bind .
Эта структура содержит локальный IP-адрес и номер порта сервера. Клиент также инициализирует адресную структуру, хранящую те же сведения. Эта структура будет использоваться в вызове connect для указания точки назначения.
Вызов bzero () помещает нули в servAddr — адресную структуру сервера. Еще раз мы трактуем семейство адресов как Интернет.
Затем нужно преобразовать введенное пользователем имя хоста в IP-адрес. Это делает функция gethostbyname , которая возвращает указатель на структуру hostent , содержащую имя сервера и IP-адрес.
Функция bcopy применяется для копирования IP-адреса (который находится в hp->h_addr ) в servAddr .
Второй введенный конечным пользователем аргумент определял порт сервера. Он читался как текстовая строка ASCII, поэтому ее сначала нужно преобразовать в целое число через atoi (), а затем изменить порядок следования байт через htons (). Наконец номер порта копируется в адресную переменную из servAddr .
bzero((char *)&servAddr, sizeof(servAddr));
servAddr.sin_family = AF_INET;
Интервал:
Закладка: