inaddr loopback что это

Понимание INADDR для программирования сокетов

5 ответов

для сервера вы обычно хотите привязаться ко всем интерфейсам, а не только к «localhost».

если вы еще не знакомы с ним, я призываю вас проверить руководство Beej по программированию сокетов:

поскольку люди все еще читают это, дополнительное Примечание:

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

в этом случае только один IP-сокет может быть привязан к любому заданному локальному (адрес, порт) пара. Когда INADDR_ANY указан в вызове bind, сокет будет привязан ко всем локальным интерфейсам.

, когда слушать(2) вызывается на несвязанном сокете, сокет автоматически привязывается к случайному бесплатно порт с локального адреса к INADDR_ANY.

, когда подключиться(2) вызывается на несвязанном сокете, сокет автоматически привязывается к случайному Свободному порту или к совместному порту с локальным адресом, установленным в INADDR_ANY.

существует несколько специальных адресов: INADDR_LOOPBACK (127.0.0.1) всегда ссылается на локальный хост через устройство loopback; INADDR_ANY (0.0.0.0) означает любой адрес обязательный.

если (sin_addr.s_addr) поле имеет значение константа INADDR_ANY, как определенными в netinet/в.ч, абонент просит сокет привязан ко всем сетевым интерфейсам на хосте. Впоследствии, UDP пакеты и TCP-соединения от всех интерфейсов (которые соответствуют связанному имени) направляются в приложение. Это становится важным, когда сервер предлагает услугу нескольким сетям. Оставив адрес не указано, сервер может принимать все UDP-пакеты и TCP-соединение запросы на порт, независимо от сетевого интерфейса какие запросы поступили.

Источник

Inaddr loopback что это

tcp_socket = socket(PF_INET, SOCK_STREAM, 0);
raw_socket = socket(PF_INET, SOCK_RAW, protocol );
udp_socket = socket(PF_INET, SOCK_DGRAM, protocol );

ОПИСАНИЕ

Интерфейс программирования совместим с интерфейсом BSD-сокетов. Более подробную информацию смотри в socket (7).

— это IP-протокол, указанный в IP-заголовке, который будет принят или отослан. Единственные возможные значения для параметра протокол

— это 0 или IPPROTO_TCP для TCP сокетов, 0 или IPPROTO_UDP для UDP сокетов. Для SOCK_RAW можно указать зарегистрированный в IANA IP-протокол, один из тех, что описаны в RFC1700.

ФОРМАТ АДРЕСА

Заметьте, что значения адреса и порта всегда хранятся в сетевом формате. В частности, это означает, что требуется вызывать htons (3) для числа, обозначающего порт. Все функции из стандартной библиотеки, манипулирующие с адресами/портами, работают с сетевым форматом.

ОПЦИИ СОКЕТА

IP_TTL Устанавливает или получает текущее значение поля Время Жизни (time to live), которое указывается в каждом пакете, который отсылается с этого сокета.

Флаги опции Их значения
Path MTU Discovery
=================== ============
IP_PMTUDISC_WANT Использовать установки
маршрутизаторов.
IP_PMTUDISC_DONT Никогда не производить
обнаружение MTU маршрута.
IP_PMTUDISC_DO Всегда производить обнаружение
MTU маршрута.

Если опция Path MTU Discovery включена, то ядро автоматически следит за MTU маршрута для каждого удаленного хоста. Если с некоторым узлом устанавливается соединение с помощью connect (2), то текущее значение MTU маршрута может быть установлено заново используя опцию сокета IP_MTU (например, после возникновения ошибки EMSGSIZE ). Значение MTU может меняться время от времени. Для сокетов без предварительного установления соединения, которые имеют несколько хостов-получателей, новое значение MTU для заданного хоста может быть получено с помощью очереди ошибок (смотри IP_RECVERR ). При каждом входящем сообщении об обновлении MTU, в очередь будет поставлена новая ошибка.

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

Чтобы запустить процесс обнаружения MTU маршрута для сокетов, не установивших соединение, можно сначала установить большой размер датаграммы (с размером заголовка до 64K) и позволить обновлениям MTU маршрута сократить его.

SYSCTL-ЗНАЧЕНИЯ

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

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

Эта опция включается автоматически, если конфигурируется маскарадинг или прозрачный прокси-сервер. neigh/* Смотри arp (7).

IOCTLS

Ioctls для конфигурирования характерных параметров устройств, описаны в netdevice (7).

ЗАМЕЧАНИЯ


КОДЫ ОШИБОК

EADDRINUSE Попытка связать сокет с уже используемым адресом. ENOPROTOOPT и EOPNOTSUPP Передана недопустимая опция. EPERM У пользователя нет достаточных полномочий, чтобы повысить приоритет, изменить конфигурацию или послать сигнал запрашиваемому процессу или группе процессов. EADDRNOTAVAIL Был запрошен несуществующий интерфейс или запрошенный исходящий адрес не является локальным. EAGAIN Действие над неблокирующим сокетом привело бы к его блокировке. ESOCKTNOSUPPORT Сокет не сконфигурирован или запрошен неизвестный тип сокета. EISCONN Функция connect (2) вызвана для сокета, уже установившего соединение. EALREADY Операция соединения на неблокируемом сокете уже находится в процессе выполнения. ECONNABORTED Соединение закрыто во время accept (2). EPIPE Соединение неожиданно закрылось или завершено другой стороной. ENOENT SIOCGSTAMP вызван для сокета, который еще не получил ни одного пакета. EHOSTUNREACH В таблице маршрутизации нет разрешенных записей, соответствующих адресу назначения. Эта ошибка может возникнуть из-за ICMP-сообщения от удаленного маршрутизатора или из-за локальной таблицы маршрутизации. ENODEV Сетевое устройство недоступно или неспособно посылать IP пакеты. ENOPKG IP-подсистема ядра не сконфигурирована. ENOBUFS, ENOMEM Недостаточно свободной памяти. Часто это означает, что распределение памяти ограничивается не размером системной памяти, а границами буфера сокета, но это не всегда так.

Протоколами более высокого уровня могут генерироваться другие ошибки; смотри tcp (7), raw (7), udp (7) и socket (7).

ВЕРСИИ

Sysctl-значения были введены в Linux 2.2.

СОВМЕСТИМОСТЬ


ОШИБКИ РЕАЛИЗАЦИИ

Не описаны ioctls для конфигурирования специфичных для IP опций интерфейса и таблиц ARP.

Получение исходного адреса назначения в msg_name с помощью MSG_ERRQUEUE функцией recvmsg (2) не работает в некоторых ядрах 2.2.

АВТОРЫ


СМОТРИ ТАКЖЕ

RFC791, где описана изначальная спецификация IP.
RFC1122, где описаны требования к хосту для IPv4.
RFC1812, где описаны требования к маршрутизатору для IPv4.

Источник

Программирование сокетов в Linux


Автор: Александр Шаргин

Опубликовано: 16.05.2001
Исправлено: 04.02.2006
Версия текста: 1.1

Введение

Socket API был впервые реализован в операционной системе Berkley UNIX. Сейчас этот программный интерфейс доступен практически в любой модификации Unix, в том числе в Linux. Хотя все реализации чем-то отличаются друг от друга, основной набор функций в них совпадает. Изначально сокеты использовались в программах на C/C++, но в настоящее время средства для работы с ними предоставляют многие языки (Perl, Java и др.).

Сокеты предоставляют весьма мощный и гибкий механизм межпроцессного взаимодействия (IPC). Они могут использоваться для организации взаимодействия программ на одном компьютере, по локальной сети или через Internet, что позволяет вам создавать распределённые приложения различной сложности. Кроме того, с их помощью можно организовать взаимодействие с программами, работающими под управлением других операционных систем. Например, под Windows существует интерфейс Window Sockets, спроектированный на основе socket API. Ниже мы увидим, насколько легко можно адаптировать существующую Unix-программу для работы под Windows.

ПРИМЕЧАНИЕ
Большая часть материала, изложенного в статье, применимо ко всему семейству ОС Unix. Тем не менее, все приводимые далее факты и демонстрационные программы проверялись только под Linux, поэтому название этой ОС и вынесено в заголовок статьи.

Основы socket API


Понятие сокета


Атрибуты сокета

Тип сокета определяет способ передачи данных по сети. Чаще других применяются:

Наконец, последний атрибут определяет протокол, используемый для передачи данных. Как мы только что видели, часто протокол однозначно определяется по домену и типу сокета. В этом случае в качестве третьего параметра функции socket можно передать 0, что соответствует протоколу по умолчанию. Тем не менее, иногда (например, при работе с низкоуровневыми сокетами) требуется задать протокол явно. Числовые идентификаторы протоколов зависят от выбранного домена; их можно найти в документации.

Адреса

Зачем понадобилось заключать всего одно поле в структуру? Дело в том, что раньше in_addr представляла собой объединение (union), содержащее гораздо большее число полей. Сейчас, когда в ней осталось всего одно поле, она продолжает использоваться для обратной совместимости.

ПРИМЕЧАНИЕ
На некоторых машинах (к PC это не относится) порядок хоста и сетевой порядок хранения байтов совпадают. Тем не менее, функции преобразования лучше применять и там, поскольку это улучшит переносимость программы. Это никак не скажется на производительности, так как препроцессор сам уберёт все «лишние» вызовы этих функций, оставив их только там, где преобразование действительно необходимо.

Установка соединения (сервер)


Установка соединения (клиент)


Обмен данными

Функция send используется для отправки данных и имеет следующий прототип.

Закрытие сокета

Параметр how может принимать одно из следующих значений:

Обработка ошибок


Отладка программ

Для простоты я буду использовать в демонстрационных примерах интерфейс внутренней петли.

Эхо-клиент и эхо-сервер

Теперь, когда мы изучили основные функции для работы с сокетами, самое время посмотреть, как они используются на практике. Для этого я написал две небольшие демонстрационные программы. Эхо-клиент посылает сообщение «Hello there!» и выводит на экран ответ сервера. Его код приведён в листинге 1. Эхо-сервер читает всё, что передаёт ему клиент, а затем просто отправляет полученные данные обратно. Его код содержится в листинге 2.

Листинг 1. Эхо-клиент.

Листинг 2. Эхо-сервер.

Обмен датаграммами

Как уже говорилось, датаграммы используются в программах довольно редко. В большинстве случаев надёжность передачи критична для приложения, и вместо изобретения собственного надёжного протокола поверх UDP программисты предпочитают использовать TCP. Тем не менее, иногда датаграммы оказываются полезны. Например, их удобно использовать при транслировании звука или видео по сети в реальном времени, особенно при широковещательном транслировании.

Листинг 3. Программа sender.

Листинг 4. Программа receiver.

Использование низкоуровневых сокетов

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


Рисунок 1

Низкоуровневые сокеты позволяют вам включать в буфер с данными заголовки некоторых протоколов. Например, вы можете включить в ваше сообщение TCP- или UDP-заголовок, предоставив системе сформировать для вас IP-заголовок, а можете вообще сформировать все заголовки самостоятельно. Разумеется, при этом вам придётся изучить работу соответствующих протоколов и строго соблюсти формат их заголовков, иначе программа работать не будет.

Чтобы проиллюстрировать всё это примером, я переписал программу sender из предыдущего раздела с использованием низкоуровневых UDP-сокетов. При этом мне пришлось вручную формировать UDP-заголовок отправляемого сообщения. Я выбрал для примера UDP, потому что у этого протокола заголовок выглядит совсем просто (рисунок 2).


Рисунок 2

Листинг 5. Программа sender с использованием низкоуровневых сокетов.

Функции для работы с адресами и DNS

В этом разделе мы обсудим несколько функций, без которых можно написать учебный пример, но без которых вряд ли обойдётся реальная программа. Поскольку для идентификации хостов в Internet широко используются доменные имена, мы должны изучить механизм преобразования их в IP-адреса. Кроме того мы изучим несколько удобных вспомогательных функций.

Эта функция получает имя хоста и возвращает указатель на структуру с его описанием. Рассмотрим эту структуру более подробно.

Читайте также:  haxlogs log что это

Следует иметь в виду, что функции gethostbyname и gethostbyaddr возвращают указатель на статическую область памяти. Это означает, что каждое новое обращение к одной из этих функций приведёт к перезаписи данных, полученных при преыдущем обращении.

Параллельное обслуживание клиентов


Способ 1

Этот способ подразумевает создание дочернего процесса для обслуживания каждого нового клиента. При этом родительский процесс занимается только прослушиванием порта и приёмом соединений. Чтобы добиться такого поведения, сразу после accept сервер вызывает функцию fork для создания дочернего процесса (я предполагаю, что вам знакома функция fork ; если нет, обратитесь к документации). Далее анализируется значение, которое вернула эта функция. В родительском процессе оно содержит идентификатор дочернего, а в дочернем процессе равно нулю. Используя этот признак, мы переходим к очередному вызову accept в родительском процессе, а дочерний процесс обслуживает клиента и завершается ( _exit ).

С использованием этой методики наш эхо-сервер перепишется, как показано в листинге 6.

Листинг 6. Эхо-сервер (версия 2, fork)

Способ 2

Листинг 7. Эхо-сервер (версия 3, неблокирующие сокеты и select).

Работа по стандартным протоколам

Как я уже говорил, сокеты могут использоваться при написании приложений, работающих по протоколам прикладного уровня Internet (HTTP, FTP, SMTP и т. д.). При этом взаимодействие клиента и сервера происходит по той же самой схеме, что и взаимодействие эхо-клиента и эхо-сервера в нашем примере. Разница в том, что данные, которыми обмениваются клиент и сервер, интерпретируются в соответствии с предписаниями соответствующего протокола.

Например, веб-сервер может работать по следующему алгоритму.

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

Как видим, в работе по стандартным протоколам нет ничего сложного или принципиально нового.

Прорыв за пределы платформы

В мире Internet взаимодействие программ, работающих на разных платформах, встречается сплошь и рядом. Так, практически ежесекундно очередной Internet Explorer подсоединяется к веб-серверу Apache, а очередной Netscape Navigator совершенно спокойно подключается к IIS. Вот почему весьма полезно писать программы так, чтобы их можно было без труда переносить на другие платформы. В этом разделе мы посмотрим, как переносить Linux-программы, использующие сокеты, на платформу Windows.

Список основных отличий socket API и Winsock API выглядит примерно так.

Если переписать наш эхо-клиент с учётом приведённых особенностей Winsock API, а затем скомпилировать его под Windows (например, с помощью Visual C++), он вполне сможет взаимодействовать с эхо-сервером, работающим под Linux. Таким образом, сокеты позволяют решить проблему кроссплатформенного взаимодействия двух приложений.

Заключение

В этой статье мы рассмотрели целый ряд важных аспектов программирования сокетов. Тем самым мы заложили прочную основу для дальнейших исследований в этой области. Разумеется, большое количество деталей осталось за рамками нашей беседы. Но теперь вы сможете самостоятельно почерпнуть недостающую информацию из man-страниц Linux и из собственного практического опыта. Желаю удачи.

Источник

Inaddr loopback что это

Эта глава описывает средства GNU для межпроцессорной связи, используя гнезда.

Не все операционные системы поддерживают гнезда. В библиотеке GNU, заглавный файл ‘sys/socket.h’ существует независимо от операционной системы, и функции гнезд всегда существуют, но если система действительно не поддерживает гнезда, эти функции всегда терпят неудачу.

Незавершенность: Мы в настоящее время не описали средства для передачи сообщений или для конфигурирования интерфейса Internet.

В заключение Вы должны выбрать протокол, чтобы установить связь. Протокол определяет какой механизм низкого уровня используется, чтобы передавать и получить данные. Каждый протокол допустим для определенного именного пространства и стиля связи; именное пространство иногда называется совокупностью протоколов из-за этого имена именных пространств начинаются с ‘PF_’.

Библиотека GNU поддерживает различные виды сокетов. В этом разделе описываются различные типы сокетов предоставляемые в бибилотекой GNU. Упомянутые в данном разделе символические константы определены в «sys/socket.h».

Более подробное описание работы с использованием этого типа Вы найдете в Разделе 11.8 [Соединения].

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

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

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

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

В первый раз, когда Вы посылаете данные из сокета, или используете его, чтобы инициализировать соединение, система назначает адрес автоматически.

Подробности адресации сокетов изменяются, в зависимости от именного пространства, которое Вы используете. См. Раздел 11.4 [Именное пространство Файла], или Раздел 11.5 [Именное пространство Internet].

Независимо от именного пространства, Вы используете те же самые функции bind и getsockname, чтобы установить и исследовать адрес гнезда.

Форматы Адреса

Функции bind и getsockname используют обобщенный тип данных struct sockaddr *, чтобы представить указатель на адрес гнезда. Вы не можете использовать этот тип данных действительно, чтобы интерпретировать адрес или создавать его; для этого, Вы должны использовать соответствующий тип данных для именного пространства гнезда.

Таким образом, обычная нужно создать адрес в соответствующем именном пространстве специфического типа, и приводить указатель на struct sockaddr *, когда Вы вызываете bind или getsockname.

Символы в этом разделе определены в заголовочном файле «sys/socket.h».

Каждый формат адреса имеет символическое имя, которое начинается с «AF_ «. Каждый из них соответствует «PF_ » символу, который обозначает соответствующее именное пространство. Вот список названий форматов адресов: AF_FILE

Это синоним AF_FILE, для совместимости. (PF_UNIX ­ аналогично синоним для PF_FILE.)

Не обозначает никакой специфический формат адреса. Он используется только в редких случаях, когда необходимо очистить снаружи заданный по умолчанию адрес адресата от «соединенного» датаграмного сокета. См. Раздел 11.9.1 [Посылка Датаграмм]. Соответствующий символ указателя именного пространства PF_UNSPEC существует для законченности, но нет никакой причины использовать его в программе.

«Sys/socket.h» определяет символы, начинающиеся с » AF_ » для различных видов сетей, большинство из которых фактически не встречается. Мы будем документировать только то, что действительно используется на практике.

Установка Адреса сокета

Используйте функцию bind, чтобы для связывания адреса сокета. Прототип для bind находится в заголовочном файле «sys/socket.h». Для примеров использования см. Раздел 11.4 [Именное пространство Файла].

заданный адрес не доступен на этой машине. EADDRINUSE

Существует другой сокет использующий заданный адрес.

сокет уже имеет адрес. EACCESS

Вам не достаточно прав для обращения к запрошенному адресу. (В области Internet, только супер-пользователю позволяют определить номер порта в диапазоне от 0 до IPPORT_RESERVED минус один; см. Раздел 11.5.3 [Порты].) Дополнительные условия могут быть возможны в зависимости от специфического именного пространства сокета.

Чтение Адреса сокета

Используйте функцию getsockname, чтобы исследовать адрес гнезда Internet. Прототип для этой функции находится в заголовочном файле «sys/socket.h».

Формат данных адреса зависит от именного пространства сокета. Длина информации обычно устанавливается для данного именного пространства, так что обычно Вы можете знать точно, сколько места необходимо. Обычно нужно зарезервировать место для значения, используя соответствующий тип данных для именного пространства сокета, и тогда привести адрес к struct sockaddr *, чтобы передать его getsockname.

не имеется достаточных внутренних буферов, доступных для операции.

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

Этот раздел описывает подробности именного пространства файла, чье символическое имя (требуется, когда Вы создаете сокет) ­ PF_FILE.

Понятия Именного пространства Файла

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

После того, как Вы закрываете сокет в именном пространстве файла, Вы должны удалить имя файла из файловой системы. Используйте unlink или remove, чтобы делать это; см. Раздел 9.5 [Удаление Файлов].

Подробности Именного пространства Файла

Чтобы создавать сокет в именном пространстве файла, используйте константу PF_FILE как аргумент именного пространства для socket или socketpair. Эта константа определена в «sys/socket.h».

Структура для определения имен сокетов в именном пространстве файла определена в заголовочном файле «sys/un.h»:

Вы должны вычислить параметр длины для адреса сокета в именном пространстве файла как сумму размера компоненты sun_family и длины (не размера резервирования!) строки имени файла.

Пример файлового-именного пространства сокетов

Вот пример, показывающий, как создавать и связывать сокет в именном пространстве файла.

Этот раздел описывает подробности протокола и соглашений именования сокетов, используемые в именном пространстве Internet.

Чтобы создать сокет в именном пространстве Internet, используйте символическое имя PF_INET этого именного пространства как аргумент именного пространства socket или socketpair. Эта макрокоманда определена в «sys/socket.h».

Формат Адреса сокета Internet

В именном пространстве Internet, адрес состоит из главного адреса и порта на этой главной ЭВМ. Кроме того, протокол, который Вы выбираете, служит как бы частью адреса, потому что местные числа порта значимы только внутри специфического протокола.

Тип данных для представления адресов в именном пространстве Internet определен в заголовочном файле «netinet/in.h».

Когда Вы вызываете bind или getsockname, Вы должны определить sizeof (struct sockaddr_in) как параметр длины при использовании адреса в именном пространстве Internet.

Главные Адреса

Каждый компьютер в Internet имеет один, или большое количество Internet адресов, т. е. числа, которые идентифицируют этот компьютер среди остальных на Internet. Пользователи обычно записывают число-адрес главной ЭВМ как последовательность из четырех чисел, отделяемых точками, например «128.52.46.32».

Каждый компьютер также имеет одно или большое количество главных имен, которые являются строками слов, отделяемых точками, например «churchy.gnu.ai.mit.edu».

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

Адреса Главной ЭВМ Internet

Сетевые числа зарегистрированы в Сетевом Информационном Центре (NIC), и разделены на три класса A, B, и C. Местные числа сетевого адреса индивидуальных машин зарегистрированы администратором в локальной сети.

Сеть класса А имеет одиночно-байтовые числа в диапазоне от 0 до 127. Сетей класса A не так уж много, но каждая из них может поддерживать очень большое количество главных ЭВМ. Сети класса В размера имеет Двух-байтовые сетевые числа, с первым байтом в диапазоне от 128 до 191. Класс C самый маленький; адреса в нем они имеют Трех-байтовые сетевые числа, с первым байтом в диапазоне 192-255. Таким образом, первый 1, 2, или 3 байты адреса Internet определяют сеть. Оставшиеся байты адреса Internet определяют адрес внутри этой сети.

Нулевая сеть класса A зарезервирована для передачи по всем сетям. Кроме того, главный номер 0 внутри каждой сети зарезервирован для передачи на все главные ЭВМ в этой сети.

127-ая сеть класса A зарезервирована для возврата цикла; Вы можете всегда использовать адрес Internet «127.0.0.1», чтобы обратиться к главной машине.

Читайте также:  что делать вечером когда тебе скучно

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

Тип Данных Главного Адреса

Адреса главной ЭВМ Internet представляются в некоторых контекстах как integers (long unsigned int). В других контекстах, integer упакован внутри структуры типа struct in_addr. Было бы лучше, если бы использование было сделано непротиворечивым.

Следующие базисные определения для Internet адреса, появляются в файле «netinet/in.h»:

Функции Главного Адреса

Это дополнительные функции для управления Internet адресацией, объявленые в «arpa/inet.h». Они представляют Internet адреса в сетевом порядке байтов; это сетевые числа и числа локальных сетевых адресов в главном порядке байтов. См. Раздел 11.5.5 [Порядок Байтов], для объяснения сетевого и главного порядка байтов.

Главные Имена

В главной базе данных каждый адрес только блок памяти h_length байт длиной. Но в других контекстах имеется неявное предположение, что Вы можете преобразовывать его в struct addr_in или long unsigned int. Главные адреса в структуре struct hostent всегда даны в сетевом порядке байтов; см. Раздел 11.5.5 [Порядок Байт].

Вы можете использовать gethostbyname или gethostbyaddr, для уточнения инфрмации базы данных главных ЭВМ относительно специфической главной ЭВМ. Информация возвращена в статически размещенной структуре.

Если происходит сбой поиска, gethostbyaddr возвращает пустой указатель.

Если поиск имени gethostbyname или gethostbyaddr окончился неудачно, Вы можете выяснить причину, рассматривая значение переменной h_errno. (Было бы правильнее установить errno, но использование h_errno совместимо с другими системами.) Перед использованием h_errno, Вы должны объявить его примерно так:

Вы можете также просматривать всю базу данных главных ЭВМ используя sethostent, gethostent, и endhostent. Будьте внимательны при использовании этих функций, потому что они не допускают повторного использования.

Если аргумент stayopen является отличным от нуля, она устанавливает флаг так, чтобы последующие обращения к gethostbyname или gethostbyaddr не закрыли базу данных (что они обычно сделали бы).

Это делается для эффективности, если Вы вызываете эти функции несколько раз, то избегаете повторного открытия базы данных для каждого обращения.

Порты Internet

Адрес сокета в именном пространстве Internet состоит из адреса Internet машины плюс номер порта, который отличает гнездо на данной машине (для данного протокола). Номера портов располагаются от 0 до 65535.

Номера портов меньше, зарезервированых IPPORT_RESERVED для стандартных серверов, типа finger и telnet. Имеется база данных, которая следит за ними, и Вы можете использовать функцию getservbyname для отображения сервисного номера порта; см. Раздел 11.5.4 [База данных Услуг].

Если Вы собираетесь устанавливать сервер, который не является стандартно определенным в базе данных, то Вам необходимо выбрать для него номер порта. Используйте номера большие чем IPPORT_USERRESERVED; такие числа зарезервированы для серверов и никогда не будут генерироваться системой.

Когда Вы используете сокет без определения адреса, система генерирует номер порта для него. Этот номер попадает в интервал между IPPORT_RESERVED и IPPORT_USERRESERVED.

На Internet, фактически, законно иметь два различных сокета с одинаковыми номерами портов, пока они оба не попытаются связаться с тем этим адресом сокета (главный адрес плюс номер порта). Вы не должны дублировать номер порта за исключением специальных обстоятельств, где протокол с более высоким уровнем требует этого. Обычно, система не будет разрешать Вам делать это; bind требует различные номера портов. Чтобы многократно использовать номер порта, Вы должны установить опцию сокета SO_REUSEADDR. См. Раздел 11.11.2 [Опции Сокетов].

Эти макрокоманды определены в заголовочном файле «netinet/in.h».

База данных Услуг

Пустой указатель завершает массив.

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

Эта функция полезна как для серверов так и для клиентов; серверы используют ее, чтобы определить, на каком порту они должны принимать пакеты (см. Раздел 11.8.2 [Прием]).

Вы можете также просматривать базу данных услуг, используя setservent, getservent, и endservent. Будьте внимательным в использовании этих функций, потому что они не предназначены для повторного использования.

Если аргумент stayopen является отличным от нуля, она устанавливает флаг так, чтобы последующие обращения к getservbyname или getservbyport не закрыли базу данных (поскольку они обычно закрыли бы). Это делается для большей эффективности, если Вы вызываете эти функции несколько раз, избегая повторного открытия базы данных для каждого обращения.

Преобразование Порядка Байтов

Различные виды компьютеров используют различные соглашения для упорядочения байтов внутри слова. Некоторые компьютеры помещают старший байт сначала (это называется «big-endian» порядком), а другие помещают его последним («little-endian» порядок).

Так, чтобы машины с различными соглашениями порядка байтов могли связываться, протоколы Internet определяют каноническое соглашение порядка байтов для данных, переданных по сети. Оно известно как сетевой порядок байта.

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

Если Вы используете getservbyname и gethostbyname или inet_addr, для получения номера порта и главного адреса, то эти значения уже в сетевом порядке байта, и Вы можете копировать их непосредственно в структуру sockaddr_in.

Иначе, Вы должны преобразовать значения явно. Используйте htons и ntohs, чтобы преобразовать значения для sin_port элемента. Используйте htonl и ntohl, чтобы преобразовать значения для sin_addr элемента. (Помните, struct in_addr эквивалентен long unsigned int.) Эти функции описаны в «netinet/in.h».

База данных Протоколов

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

Протоколы Internet вообще определены именем вместо номера. Сетевые протоколы, которые знает главная ЭВМ, сохранены в базе данных. Она обычно происходит от файла «/etc/protocols», или может быть эквивалент, обеспеченный блоком преобразования имен. Вы можете искать номер протокола, связанный с именованным протоколом в базе данных, используя getprotobyname функцию.

Имеются детализированные описания утилит для доступа к базе данных протоколов. Они объявлены в «netdb.h».

Вы можете использовать getprotobyname и getprotobynumber, чтобы искать в базе данных протоколов специфический протокол. Информация возвращается в статически размещенной структуре; Вы должны копировать информацию, если Вы хотите сохранить ее для следующих обращений.

Вы можете также просматривать целую базу данных протоколов (по одному протоколу одновременно), используя setprotoent, getprotoent, и endprotoent. Будьте внимательным в использовании этих функций, потому что они не предназначены для повторного использования.

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

Пример Internet сокета.

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

Конечно другие именные пространства и связанные семейства протоколов также реализованы, но не описаны здесь, потому что они редко используются. PF_NS обращается к протоколам Программного обеспечения Сети Ксерокса (Xerox Network Software). PF_ISO замещает Открытые системы Связи (Open Systems Interconnect). PF_CCITT обращается к протоколам из МККТТ (CCITT). «Socket.h» определяет эти символы и другие протоколы.

PF_IMPLINK используется для связи между главными ЭВМ и Процессорами Сообщений Internet.

Этот раздел описывает фактические библиотечные функции для открытия и закрытия сокетов. Те же самые функции работают для всех именных пространств и стилей соединения.

Создание сокета.

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

EMFILE процесс имеет слишком много открытых описателей файла.

система имеет слишком много открытыми описателей файла

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

в системе закончилось внутреннее пространство буфера. Описатель файла, возвращенный функцией socket поддерживает и чтение и запись. Но, подобно трубопроводам, сокеты не поддерживают операции позиционирования файла.

Пример вызова функции socket см. Раздел 11.4 [Именное пространство Файла].

Закрытие сокета.

Когда Вы закончили использование сокета, Вы можете просто закрыть описатель файла примитивом close; см. Раздел 8.1 [Открытие и Закрытие Файлов].

Вы можете также выключать только прием или только передачу на соединении, вызывая shutdown, которая объявлена в «sys/socket.h».

socket не соединен.

Пары сокетов

Пара socket состоит из пары соединенных (но неименованных) сокетов. Это очень похоже на трубопровод и используется аналогичным способом. Пары сокетов создаются функцией socketpair, описание в файле «sys/socket.h».

Аргументы namespace, style и protocol интерпретируется как в функции socket. style должен быть один из стилей связи, перечисленных в Разделе 11.2 [Стили связb]. Аргумент именного пространства определяет именное пространство, которое должно быть AF_FILE (см. Раздел 11.4 [Именное пространство Файла]); protocol определяет протокол связи.

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

Процесс имеет слишком много открытых описателей файла. EAFNOSUPPORT

Не обеспечивается заданное именное пространство. EPROTONOSUPPORT

Не обеспечивается заданный протокол. EOPNOTSUPP

Заданный протокол не поддерживает создание пар сокетов.

Создание Соединения

В создании соединения, клиент делает соединение, в то время как сервер ждет и принимает соединение. Здесь мы обсуждаем то, что клиентская программа должна делать, используя функцию connect, которая объявлена в «sys/socket.h».

Обычно, connect ждет, пока сервер не отвечает на запрос прежде. Вы можете устанавливать режим неблокирования на сокете socket, чтобы заставить connect возвратиться немедленно без ожидания ответа. См. Раздел 8.10 [Флаги Состояния Файла], для уточнения инфрмации относительно неблокирования.

заданный адрес не доступен на отдаленной машине.

именное пространство addr не обеспечивается этим сокетом.

указанный сокет уже соединен.

попытка установить соединение не состоялась.

сервер активно отказался устанавливать соединение.

сеть данного addr не доступна с этой главной ЭВМ.

адрес сокета для данного addr уже используется.

указанный сокет не-блокируемый, и соединение не могло бы быть установлено немедленно.

указанный сокет не-блокируемый и уже имеет отложенное соединение.

Ожидание Соединений

Теперь рассмотрим то, что процесс сервера должен делать, чтобы принять соединение из сокета. Это включает использование функции listen, чтобы дать возможность запросам на соединения через сокет, и позже использование функции accept (см. Раздел 11.8.3 [Принятие Соединений] ) чтобы действовать по запросу. Функция listen используется только для уже установленного логического соединения.

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

В именном пространстве Файла, обычные биты защиты файла управляют доступом к сокету.

Аргумент n определяет длину очереди для отложенных соединений.

указанный сокет не поддерживает эту операцию.

Принятие Соединений

Когда сервер получает запрос соединения, он может создать соединение, принимая запрос. Для этих целей следует использовать функцию accept.

Читайте также:  какой клей для обуви самый надежный

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

Исходный сокет сервера остается доступным для ожидания дальнейших запросов соединения.

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

Функция accept находится в состоянии ожидания, когда нет возможности принять соединение, если, конечно, указанный сокет не имеет набор режимов неблокирования. (Вы можете использовать select, чтобы ждать отложенное соединение на неблокируемом сокете.) См. Раздел 8.10 [Флаги Состояния Файла], для уточнения информации относительно режима неблокирования.

Аргументы Addr и length_ptr используется, чтобы возвратить информацию относительно имени клиентского сокета, которое инициализировало соединение. См. Раздел 11.3 [Адреса сокетов], для уточнения информации относительно формата.

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

описанный сокет не поддерживает эту операцию.

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

Кто соединен со Мной?

указанный сокет не соединен.

нет внутренних доступных буферов.

Пересылка Данных


Посылка Данных

Функция send объявлена в файле «sys/socket.h». Если ваш аргумент flags нуль, Вы можете точно также использовать write вместо send. Если сокет был соединен, но соединение прервано, Вы получаете сигнал SIGPIPE для каждого использования send или write (см. Раздел 21.2.6 [Разнообразные Сигналы]).

Обратите внимание, что успешное возвращаемое значение просто указывает, что сообщение было послано без ошибки, и не обязательно, что оно было получено без ошибки. В переменной errno определяются следующие коды ошибок для этой функции: EBADF

операция был прервана сигналом прежде, чем любые данные были посланы. См. Раздел 21.5 [Прерванные Примитивы].

тип сокетаа требует, чтобы сообщение было послано быстро, но сообщение слишком большое для этого.

на сокете был установле режим неблокирования, а операция записи блокирует. (Обычно send блокирует, пока операция не может быть завершена.)

не имеется достаточного внутреннего доступного пространства буфера.

Вы не соединили этот сокет.

Этот сокет был соединен, но соединение теперь разбито. В этом случае send генерирует SIGPIPE сначала; если этот сигнал игнорируется или блокируется, или если обработчик возвращается, то происходит сбой send с EPIPE.

Получение Данных

Функция recv объявлена в файле «sys/socket.h». Если ваш аргумент flags является нулем, Вы можете точно также использовать read вместо recv; см. Раздел 8.2 [Примитивы ввода-вывода].

Если режим неблокирования установлен для сокета, и никакие данные не доступны для чтения, recv не ожидает, а сразу возвращает код ошибки. См. Раздел 8.10 [Флаги Состояния Файла], для уточнения информации относительно режима неблокирования.

Режим неблокирования был установлен на сокете. (Обычно, recv блокирует пока не имеется входа, доступного для чтения.)

операция была прервана сигналом прежде, чем любые данные прочитались. См. Раздел 21.5 [Прерванные Примитивы].

Вы не соединили этот сокет.

Опции Данных сокета.


Пример сокета с потоком байтов.

Вот пример программы клиента, которая устанавливает соединение для сокета в пространстве Internet с поточным типом передачи данных. Она не делает ни чего особенно интересного; если она соединилась с сервером, она посылает текстовую строку серверу и выходит.

Этот специфический сервер не делает хоть что-нибудь интересное, если он получил сообщение от клиента, то он закрывает сокет клиента по получению признака конца файла.

Эта программа использует make_socket и init_sockaddr для устанавления адреса сокета; см. раздел 11.5.7 [Inet Пример].

Данные Вне потока

Данные вне потока посылаются с высшим приоритетом, плюс процесс получения не обрабатывает их в обыкновенное очереди, но чтобы читать доступные данные вне потока следует использовать recv с флагом MSG_OOB (см. Раздел 11.8.5.2 [Получение Данных]). Обычные операции чтения не воспринимают данные вне потока; они читают только обычные данные.

Когда сокет находит, что данные вне потока продвигаются, он посылает сигнал SIGURG процессу владельца или группе процессов сокета. Вы можете определять владельца, используя команду F_SETOWN для функции fcntl; см. Раздел 8.12 [Ввод Прерывания]. Вы должны также установить обработчик для этого сигнала, как описано в Главе 21 [Обработка Сигналов], для соответствующего действия типа чтения данных вне потока.

Уведомление о данных вне потока (с SIGURG или с select) обозначает, что данные вне потока находятся в пути; данные не могут фактически прибывать позже. Если Вы пробуете читать данные вне потока прежде, чем они ппребывают, то recv генерирует ошибку с кодом EWOULDBLOCK.

Датаграмные пакеты подобны письмам: Вы посылаете каждый независимо, с собственным адресом адресата, и они могут прибывать в неправильном порядке или вообще не прибывать.

Функции listen и accept не предназначены для сокетов, использующих стили связи без установки логического соединения.

Посылка Датаграмм

Нормальный способ посылки данных относительно датаграмного сокета использует функцию sendto, объявленную в «sys/socket.h».

Flags интерпретируется также как и в send; см. Раздел 11.8.5.3 [Опции данных сокетов].

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

Также возможно, что для одного обращения к sendto она сообщит ошибку из-за проблемы связанной с предыдущим обращением.

Получение Датаграмм

Функция recvfrom читает пакет из датаграмного сокета и также сообщает Вам, откуда он был послан. Эта функция объявлена в «sys/socket.h».

Аргумент size определяет максимальное число байтов, которые нужно читать.

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

Аргументы addr и length_ptr используются для возвращения адреса источника пакета. См. Раздел 11.3 [Адреса сокетов]. Для сокета в области файла, информация адреса не будет значима, так как Вы не можете читать адрес такого сокета (см. Раздел 11.4 [Именное пространство Файла] ). Вы можете определять пустой указатель как аргумент addr, если Вы не заинтересованы в этой информации.

Вы можете использовать recv (см. Раздел 11.8.5.2 [Получение Данных]) вместо recvfrom, если знаете, что не должны выяснить, кто послал пакет. Даже read, может использоваться, если Вы не хотите определять flags (см. Раздел 8.2 [Примитивы ввода ­ вывода]).

Датаграмный Пример сокета.

Вот набор примеров программ, которые посылают сообщения используя датаграмный стиль. И клиент и сервер используют функцию make_named_socket, которая была предоставлена в Разделе 11.4 [Именное пространство Файла], для создания и связывания сокетов.

Сначала программа сервера. Очевидно, это не особенно полезная программа, но она показывает общие идеи.

Пример Чтения Датаграмм

Вот программа клиента, соответствующая серверу выше.

Она посылает датаграмму серверу и ждет ответ. Обратите внимание, что сокету клиента (также как для сервера) в этом примере должно быть дано имя. Так, чтобы сервер мог направлять сообщение обратно клиенту. Так как сокет не имеет никакого связанного состояния соединения, единственый способ, которым сервер может сделать это ссылаясь на имя клиента.

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

Inetd Серверы

Написание программы сервера, которая будет выполнена inetd очень просто. Каждый раз когда кто-то запрашивает соединение с соответствующим портом, стартует новый процесс сервера. Соединение уже существует в это время; гнездо доступно как описатель стандартного ввода и как описатель стандартного вывода (описатели 0 и 1) в процессе сервера. Так что программа сервера может начинать читать и писать данные сразу же. Часто программа нуждается только в обычных средствах ввода-вывода; фактически, универсальная программа-фильтр, которая не знает ничего относительно сокетов, может работать как сервер потока байтов, запускаемая inetd.

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

Конфигурирование inetd

Имеются два стандартных входа в «/etc/inetd.conf»:

Поле wait должно быть, или «wait» или «nowait». «wait» используется, если стиль не требует установления логического соединения и обрабатывает многократные запросы. «nowait» используется, когда необходимо,чтобы inetd начинал новый процесс для каждого сообщения, или запроса, который приходит. Если используется соединение, то wait должен быть «nowait».

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

Если Вы редактируете «/etc/inetd.conf», то Вы можете указывать необходимость повторного чтения файла для inetd и сообщения нового содержимого, посылая inetd сигнал SIGHUP. Вы будете должны использовать ps, чтобы определить ID процесса inetd, поскольку оно не фиксировано.

Этот раздел описывает, как читать или установить различные опции, которые изменяют поведение сокетов и их основных протоколов связи.

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

Функции Опций сокета.

Имеются функции для исследования и изменения опций сокета. Они объявлены в «sys/socket.h».

Значение опции сохранено в буфере, на который указывает optval. Перед обращением, Вы должны обеспечить в * optlen_ptr размер этого буфера; по возвращении, он содержит число байтов информации, фактически сохраненной в буфере.

Большинство опций интерпретирует буфер optval как одиночное значение int.

Optname не имеет смысла для данного уровня.

Возвращаемое значение и коды ошибки для setsockopt такие же как для getsockopt.

Опции уровня сокета.

Вот таблица имен опций уровня сокета; все они определены в файле «sys/socket.h».

Значение имеет тип int; значение отличное от нуля означает «да».

Много систем приходят с базой данных, которая записывает список сетей, известных разработчику системы. Она обычно сохраняется или в файле «/etc/networks» или в блоке преобразования имен. Эта база данных полезна для маршрутизации программ типа route, но бесполезна для программ, которые просто связываются по сети. Функции предназначенные для обращения к этой базе данных описаны в «netdb.h «.

Он имеет следующие элементы:

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

Источник

Сказочный портал