Пример работы с сокетами (socket) для windows


Содержание

TCP и UDP сокеты в CODESYS V3

CPM723-01: Рекомендации к применению

Сопроводительные документы

Сокеты и стек протоколов TCP/IP

Рис. 1. Пример протоколов стека TCP/IP в соответствии с моделью OSI

В распределенных системах управления обмен данными является одним из ключевых моментов работы системы. Контроллер CPM723-01 позволяет отправлять и получать данные по промышленному протоколу Modbus TCP на базе протокола TCP/IP с использованием двух портов Ethernet и по протоколу Modbus RTU/ACSII на базе последовательных сетей RS-485/ RS-232 с помощью коммуникационных модулей NIM741/NIM742. Кроме того, система исполнения контроллера CPM723-01 поддерживает механизм сетевого обмена данными между контроллерами, принадлежащими одной подсети, средствами специального протокола прикладного уровня CODESYS V3.

Иногда возникает необходимость использовать протоколы низкого уровня, которые позволяют обмениваться большим количеством сообщений с помощью стека TCP/IP. Также, на базе них можно создавать протоколы более высокого уровня модели OSI (рис. 1).

Взаимодействие между устройствами в рамках стека TCP/IP осуществляется с помощью связки IP адреса и порта.

Для заданияIP адресав настоящее время чаще всего используется протокол IPv4. Для него IP-адрес записывается в виде 32-битной формы, представляемой в символьной форме mmm.nnn.ppp.qqq: адрес, разбитый на четыре поля, разделённых точками, по одному байту в поле, например, 192.168.102.101. Номер порта задается в диапазоне от 0 до 65535.

Пара адрес и порт образует сокет (с английского socket – «гнездо»). Сокет – является программным интерфейсом, который обеспечивает обмен данными между устройствами на низком уровне (рис. 2).

Рис. 2. Общение с помощью сокетов.

Протокол TCP/IP основывается на соединениях, устанавливаемых между двумя компьютерами, обычно называемых клиентом и сервером. Поэтому, различают сокет клиента и сокет сервера. Для организации общения клиент должен знать IP адрес и номер порта сервера, по которым он подключается к удаленному устройству. в рамках стека протоколов TCP/IP различают два типа сокетов TCP и UDP. Также, TCP сокеты называют потоковыми, а UDP – датаграммными.

Протокол TCP/IP основывается на соединениях, устанавливаемых между двумя компьютерами, обычно называемых клиентом и сервером. Поэтому, различают сокет клиента и сокет сервера. Для организации общения клиент должен знать IP-адрес и номер порта сервера, по которым он подключается к удаленному устройству. в рамках стека протоколов TCP/IP различают два типа сокетов TCP и UDP. Также, TCP сокеты называют потоковыми, а UDP – датаграммными.

TCP сокеты

TCP сокеты используют TCP-соединения, в которых на транспортном уровне (рис. 1) обеспечивается надёжная доставка данных. TCP протокол отвечает за установление и поддержание соединения, сегментацию, доставку и буферизацию данных, упорядочивание и избавление от дублированных TCP-сегментов данных, контроль ошибок и скорости передачи. Схема работы простого TCP сокета представлена на рисунке 3.

Для удобства в качестве функций, указанных на диаграмме, используются функции, из системной библиотеки SysSocket 3.х.x.x, которая позволяет создавать сокеты на устройствах, поддерживающих платформу CODESYS V3 в том числе на контроллере CPM723-01 модульной линейки Fastwel I/O.

Cерверный TCP сокет

Рассмотрим работу серверного сокета (рис. 3). Будем считать, что существует отдельная программа, исполняемая в контроллере, которая организует обмен данными с помощью сокетов.

Рис. 3. Работа простого TCP сокета

Инициализация сокета

При старте программы происходит инициализация сервера. С помощью функции SysSockCreate() создается системный идентификатор (handle) сокета. Данная функция в качестве входных параметров принимает аргументы, задающие тип и протокол сокета. Для использования TCP протокола функция SysSockCreate() должна принимать следующие входные аргументы:

Далее сокет сервера привязывается к определенному IP-адресу и порту с помощью функции SysSockBind() . Для привязки к определенному IP-адресу функция SysSockBind() ссылается на структуру SOCKADDRESS , в которой хранятся заданный адрес сокета для привязки.

После успешной привязки к адресу функция SysSockListen() включает прослушивание входящих соединений (ожидание подключений клиентов к серверу). Функцией SysSockListen() также определяется максимальное количество подключений к серверу. Например, если максимальное количество подключений равно 3, и если 3 клиента уже подключились к серверу, то 4-тому будет отказано в подключении.

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

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

Серверный сокет принимает сообщения с помощью функции SysSockRecv() :

Затем отправляет данные с помощью функции SysSockSend() :

Обработка новых подключений

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

  • 1. Программа может закрыть клиентское соединение. В таком случае, в следующих циклах программы сервер будет ожидать подключения с новым клиентом. Такой режим работы не является эффективным, так как контроллеру придется во время каждого цикла закрывать клиентское соединение и подключать нового (или того же самого что и в предыдущем цикле) клиента.
  • 2. Программа может не закрывать клиентский сокет, а сохранить установленное соединение. В таком случае, один раз установив соединение, клиент будет постоянно отправлять и получать данные от сервера. Такой режим работы более эффективный, но может возникнуть ситуация, когда все клиентские соединения будут заняты, и новый клиент не сможет подключиться к серверу. Решить данную ситуацию можно различными способами. Один из вариантов – следить за последним временем активности клиентских сокетов, и отключать самое старое соединение в случае, если в очереди обнаружился новый клиент (рис. 4).
Рис. 4. Обработка подключения нового клиента

Закрытие соединения

В рабочем режиме работы серверный сокет всегда остается открытым. Закрытие серверного сокета может происходить при внешнем событии, или при возникновении критических ошибок. Ошибки при создании и работе сокетов отображаются в системном идентификаторе result, который имеет тип структуры RTS_IEC_RESULT. Обозначение кодов ошибок описано в системной библиотеке CmpErrors Interfaces в глобальных константах Errors (рис. 5).
Для закрытии сокетного соединения используется фукнция SysSockClose() :

Рис. 5. Расшифровка кодов ошибок работы сокетов

Клиентский TCP сокет

Схема работы клиентского сокета отображена на рисунке 3 справа.

Инициализация клиента

Функция SysSockCreate() создает системный идентификатор сокета. Также, как и для сервера, для клиента необходимо создать потоковый сокет:

Зная IP-адрес и порт сервера, клиент с помощью SysSockConnect() подключается к серверному сокету:

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

Обмен данными между клиентом и с помощью функций SysSockSend() и SysSockRecv() :

Закрытие соединения

После обмена данными сокет может быть закрыт с помощью с помощью SysSockClose() :

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

Особенности сокетов TCP

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

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

UDP сокеты

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

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

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

Серверный UDP сокет

На рисунке 6 показана схема работы простого UDP сокета.

Инициализация сервера

Также, как в случае TCP сокетов, системный идентификатор UDP сокета создается с помощью функции SysSockCreate() :

После создания сокет сервера привязывается к определенному IP-адресу и порту с помощью функции SysSockBind() . В отличие от TCP, UDP сокет не включает прослушивание входящих соединений, а сразу подготавливается к получению данных по сети:

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

Для получения данных по UDP сокетам используется функция SysSockRecvFrom() (в отличие от SysSockRecv() для TCP сокетов). Ее главная особенность в том, что она не просто принимает данные от клиента, но и записывает адрес и порт клиента в специальную структуру для хранения адреса SOCKADDRESS , чтобы в дальнейшем сервер знал, куда отправлять ответное сообщение:

Рис. 6. Схема работы простого UDP сокета.

Ответное сообщение отправляется с помощью SysSockSendTo() , которая аналогична SysSockSend() для TCP протокола, но в качестве аргумента принимает ссылку на адрес структуры SOCKADDRESS , где хранится записанный ранее адрес клиента:

Закрытие соединения

После отправки данных, сокет сервера снова переходит к функции SysSockRecvFrom() и остается незакрытым.

Но в случае необходимости серверный сокет можно закрыть аналогично TCP сокету:

Клиентский UDP сокет

Клиент UDP работает аналогично клиентскому сокету TCP за исключением использования функций SysSockSendTo() и SysSockRecvFrom() для отправки и получения сообщений.

Инициализация клиента

Функция SysSockCreate() создает системный идентификатор сокета. Также, как и для сервера, для клиента необходимо создать потоковый сокет:

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

В отличие от TCP сокетов, при использовании UDP протокола клиентский сокет не устанавливает соединения с сервером, а сразу после создания клиентского сокета переходит к обмену данными с помощью функций SysSockSendTo() и SysSockRecvFrom() :

bytesRecv:=SysSockRecvFrom(hClientSocket, ADR(recvMessage), 256, 0, ADR(clientAddress), SIZEOF(clientAddress), ADR(result));
// hClientSocket — системный идентификатор сокета сервера;
// bytesRead, bytesRecv – количество полученных и отправленных байт;
// В случае ошибки возвращается 0;
// ADR(clientAddress) – указатель на структуру SOCKADDRESS, в которую запишется адрес клиента;
// ADR(result) – указатель на идентификатор результата

Закрытие соединения

После обмена данными сокет может быть закрыт с помощью с помощью SysSockClose() :

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

Дополнительные настройки сокетов

На рисунке 3 и 6 показана работа простых серверного и клиентского сокетов. Но на деле, такая простая схема имеет некоторые ограничения и недостатки.

Блокирующий режим

По умолчанию, некоторые функции библиотеки SysSocket являются блокирующими. Это значит, что вызов функции не возвращает управление коду, до тех пор, пока он не выполнится. Блокирующими функциями являются SysSockAccept() , SysSockSend() , SysSockRecv() , SysSockSendTo() , SysSockRecvFrom() и так далее.

Например, сервер включает прослушивание входящих соединений с помощью неблокирующей функции SysSockListen() , сразу после которой идет вызов SysSockAccept() . И до тех пор, пока в очереди установленных соединений не появится хотя бы одно подключение, программа не будет исполняться дальше. Такой режим работы также называется синхронным.

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

Для того чтобы использовать функции в неблокирующем режиме, необходимо после создания сокета SysSockCreate() вызвать функцию SysSockIoctl() с входным аргументом SOCKET_FIONBIO , которая является командой перевода сокета в неблокирующий режим. При неблокирующим (асинхронном) режиме функция возвращает управление программе вне зависимости от того, закончена операция приема/передачи или нет:

Также, дополнительные настройки работы сокета можно сделать с помощью функции SysSockSetOptions() . Например, включить возможность повторного использования порта:

Подключение несколько клиентов

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

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

Если хотя бы один сокет клиента готов, например, к отправке данных, SysSockSelect() сообщит об этом программе и соединение с данным клиентом будет установлено. Схема работы серверного сокета с использованием SysSockSelect() показана на рисунке 5.

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

Рис. 7. Схема работы сокетов с использованием функции SysSockSelect()

Программа сокетов для CPM723

В проектах TCP_UDP_Sockets.project и 2xPLCs_Sockets.project, входящих в комплект поставки программного обеспечения Fastwel I/O, реализованы программы TCP сокетов и UDP сокетов на языках ST и CFC стандарта МЭК 61131-3.

Структура проекта TCP_UDP_Sockets.project указана на рисунке 8. В данном проекте реализовано два проекта для UDP и TCP сокетов, для работы в рамках одного контроллера CPM723-01. В первом проекте CPM723_LOCAL_CFC работа сокетов реализована с помощью функциональных блоков, вызываемых в программах (язык CFC). Во втором проекте CPM723_LOCAL_ST работа сокетов реализована в программах (язык ST).

Рис. 8. Структура проекта TCP_UDP_Sockets.project

В проекте 2xPLCs_Sockets.project реализован пример для двух контроллеров CPM723-01, обменивающихся данными по протоколу TCP. На первом контроллере ClientsTCP реализованы TCP сокеты клиентов, на втором контроллере ServerTCP – TCP сокет сервера. Структура проекта указана на рисунке 9.

Рис. 8. Структура проекта TCP_UDP_Sockets.project

Заключение

Сокеты отвечают за обмен данными между различными устройствами и процессами. На базе обмена данными по сокетам можно создавать протоколы стека TCP/IP более высокого уровня.

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

Пример работы с сокетами (socket) для windows

Я люблю учить на примерах, так что как насчет программы, использующей TCP/IP, которая подключается к Интернету, посылает HTTP-запрос на Web-сервер и отображает главную страницу сайта? Перед тем, как я перейду к коду, посмотрите на рис. 14.10, где показано что именно мы будем делать.

Рис. 14.10. Ход выполнения простой программы, использующей сокеты

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

Программа Sockets_Receive

Я реализовал код, необходимый для воссоздания этапов, изображенных на рис. 14.10. Загрузите программу Sockets_Receive и следуйте за мной. Проект состоит из файла main.cpp и единственной библиотеки ws2_32.lib , которая содержит все, что необходимо для программирования сокетов в Windows. Скомпилируйте программу и запустите ее. Вы увидите окно консольного приложения, в котором отображается содержимое главной страницы сайта, имя которого задано в коде. Как это должно выглядеть, показано на рис. 14.11.

Рис. 14.11. Окно программы Sockets_Receive

Открыв файл main.cpp вы увидите следующий код:

Включение заголовочного файла WinSock

Заголовочный файл winsock.h содержит всю необходимую информацию для работы с библиотекой сокетов ws2_32.lib . Убедитесь, что включаете его в любой ваш код, который работает с сокетами. Остальные заголовочные файлы применяются ежедневно в обычном программировании.

Установка версии WinSock

Перед тем, как вы вообще сможете использовать какие-либо сокеты, необходимо инициализировать систему сокетов Windows, вызвав функцию WSAStartup(). Эта функция получает номер версии сокетов, которую вы намереваетесь использовать и инициализирует коммуникационную систему. Раз вы хотите использовать сокеты версии 2, установите номер запрашиваемой версии равным 2.

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

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

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

Поиск сервера по URL

Если вы хотите установить соединение с сервером, используя URL, а не IP-адрес, вам сперва надо будет найти IP-адрес по URL. Это делается с помощью функции gethostbyname(). Она получает имя сервера и преобразует его в соответствующий IP-адрес.

Установка номера порта

Сервер может принимать подключения по нескольким линиям связи. Каждая из таких линий называется портом. Поскольку предоставляется несколько портов на выбор, необходимо указывать конкретный порт, с которым вы хотите соединиться. Это делается путем указания номера порта во время инициализации структуры адреса сервера sockaddr_in. Требуемая информация содержится в поле sin_port вышеупомянутой структуры. Задайте значение переменной sin_port и вы готовы идти дальше.

Подключение к серверу

После того, как заданы IP-адрес и порт, вы можете подключаться к серверу. Это делается путем вызова предоставляемой сокетом функции connect(). Ей передаются дескриптор сокета, который вы хотите использовать, и параметры сервера к которому вы хотите подключиться. Если функция возвращает значение SOCKET_ERROR, значит произошла ошибка; в противном случае соединение установлено.

Отправка данных серверу

Теперь, когда соединение с сервером установлено, можно отправить пакет с HTTP-запросом. Этот пакет сообщает серверу, что вы хотите увидеть содержимое предоставляемой по умолчанию веб-страницы. Для отправки пакета необходимо воспользоваться функцией send(). Она получает сокет, через который будут отправлены данные, сами отправляемые данные и их размер. В рассматриваемом примере я отправляю содержимое буфера szSendBuffer через сокет, идентификатор которого хранится в переменной skSocket.

Илон Маск рекомендует:  Что такое код booleansбулевы

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

Получение данных от сервера

После того, как вы отправили HTTP-запрос серверу, следует получить ответ от него. Чтобы увидеть ответ, вы должны вызвать функцию recv(), которая вернет данные из буфера связи сокета. Самое лучшее в сокетах то, что они автоматически принимают данные и помещают их в системный буфер, так что вам не следует беспокоиться, что данные могут быть потеряны из-за того, что ваша программа занята. Тем не менее, следует проявлять осторожность и не ждать слишком долго, поскольку данные, которые находятся в буфере слишком долго будут потеряны.

Функции приема в параметрах передаются идентификатор сокета, от которого вы хотите получить информацию, буфер для размещения данных и его размер. Как только появятся какие-нибудь данные для получения, они будут переданы в буфер приема и программа продолжит работу. Если данные никогда не будут отправлены, функция будет ждать вечно, пока вы не завершите программу. Такова природа синхронных сокетов (blocking socket).

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

После того, как функция приема данных вернет управление программе, вы можете взглянуть на содержимое веб-страницы, выведя на экран буфер szRecvBuffer.

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

Теперь, когда работа с сокетом завершена, необходимо закрыть его. Это делает функция closesocket(). Она получает идентификатор сокета, который будет закрыт и отключен.

Отключение сокетов

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

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

Программирование сетевых походовых игр

Как вы знаете, есть два типа стратегических игр: походовые и реального времени. Хотели ли вы когда-нибудь создать походовую игру, в которую можно играть через Интернет? Я говорю о том, что коллективные игры доставляют много удовольствия, но не слишком удобны, потому что игрокам необходимо собраться в одном месте. Здесь на сцену выходит программа, которую я сейчас опишу. В сопроводительных файлах к книге есть проект Sockets_TurnGame . Будучи скомпилированной, эта программа демонстрирует как осуществляется походовая игра в локальной сети или через Интернет. Пойдемте дальше и загрузим этот проект.

Ход выполнения походовой игры

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

Рис. 14.12. Ход выполнения походовой сетевой игры

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

Программа Sockets_TurnGame

Программа Sockets_TurnGame предлагает пример реализации схемы, изображенной на рис. 14.12. Запустите программу и вы увидите окно, изображенное на рис. 14.13.

Рис. 14.13. Окно программы Sockets_TurnGame

На рис. 14.13 изображено небольшое окно с элементами управления, позволяющими работать как главный компьютер или установить соединение. Щелчок по кнопке Host переключает программу в режим игрового сервера, а щелчок по кнопке Connect переключает программу в режим клиента. Так как нельзя получить цыпленка раньше яйца, вы должны сначала запустить программу главного компьютера и уже потом подключаться к ней посредством клиента.

Если вы до сих пор не поняли, чтобы программа работала должным образом, вам необходимо запустить ее дважды. Это необходимо потому, что для демонстрации передачи ходов туда и обратно необходим как ведущий компьютер, так и клиент. Если вы еще не сделали этого, запустите программу дважды и в одном из экземпляров щелкните по кнопке Host. После этого в другом экземпляре программы щелкните по кнопке Connect. В результате вы должны увидеть что-нибудь, напоминающее рис. 14.14.

Рис. 14.14. Клиент установил соединение с сервером

На рис. 14.14 и на вашем экране вы видите два экземпляра программы. Программа сервера должна ожидать, пока клиент сделает свой ход, и у программы клиента должна быть готовая к использованию кнопка Turn Done. Игрок, у которого видна кнопка Turn Done в данный момент получил контроль над игрой и может передать его другому игроку, щелкнув по кнопке. Так вы можете передавать ход туда и обратно, щелкая по появляющейся кнопке. Я знаю, что понадобится напрячь воображение, но попытайтесь представить себе, что между щелчками по кнопке вы выполняете сложные игровые ходы.

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

Рис. 14.15. Ход выполнения программы Sockets_TurnGame

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

Код проекта содержится в файлах main.cpp и main.h . Для работы программе требуются две библиотеки: winmm.lib и ws2_32.lib . Библиотека winmm.lib не требуется для работы с сетью, я использую ее для воспроизведения звукового сигнала, когда пользователь щелкает по кнопке завершения хода.

Глобальные переменные программы Sockets_TurnGame

Загрузите заголовочный файл main.h , и вы увидите в нем такой код:

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

Логическое значение g_bIsServer сообщает вам работает ли программа в режиме ведущего компьютера. Если значение равно 1, значит программа является сервером и должна ожидать подключения клиента. Если значение равно 0, программа является клиентом и должна установить соединение с ведущим игровым компьютером.

Логическое значение g_bMyTurn сообщает принадлежит ли вам в данный момент право хода в игре. Если сейчас ваш ход, будет отображаться кнопка Turn Done, щелкнув по которой вы передадите ход другому игроку. Если сейчас ваш ход, значение переменной равно 1, если нет — значение переменной равно 0.

Логическое значение g_bConnected сообщает вам установила ли программа соединение с другим игроком. 1 означает что соединение существует, 0 — что нет.

Есть и еще несколько глобальных переменных, но они относятся к элементам управления Windows и другим подобным вещам.

Функции программы Sockets_TurnGame

Далее в заголовочном файле main.h приведены прототипы используемых в программе функций. Вот они:

Функция vHost() вызывается когда пользователь щелкает по кнопке Host. Она прослушивает указанный порт на ведущем компьютере и ждет входящих подключений. Как только клиент установит соединение, ведущий компьютер принимает его, после чего можно производить обмен данными.

Функция vInitializeSockets() используется для начальной инициализации WinSock.

Функция vShutdownSockets() отключает все активные соединения и систему WinSock.

Функция vConnect() вызывается когда пользователь щелкает по кнопке Connect. Она пытается подключиться к ведущему компьютеру, чей IP-адрес указан в окне. После того, как соединение установлено, клиент получает контроль над игрой и может закончить ход в выбранный им момент времени.

Функция vSendTurnMessage() отправляет сообщающий о завершении хода пакет другому игроку. На самом деле пакет не содержит никакой полезной информации, он просто показывает вам как пересылать данные по проводам.

Функция vReceiveTurnMessage() ждет, пока другой игрок не пришлет сообщающий о завершении хода пакет. Функция будет сидеть и ждать, пока пока рак на горе не свистнет.

Функция vTurnDone() вызывается функциями отправки и приема хода для завершения хода. Это происходит когда пользователь щелкает по кнопке Turn Done.

Остальные перечисленные в заголовочном файле main.h функции являются стандартным каркасом приложения для Windows и не слишком интересны, поэтому я не буду их рассматривать. Вы же не хотите, чтобы я по сто раз описывал одно и то же? Лучше я лишний раз сыграю в Age of Mythology!

Функция vHost()

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

Первая часть кода реализует логику для подключения клиента. Фактически программа прослушивает порт, ожидая соединения и принимает соединение, когда оно происходит. После этого код убирает кнопки Host и Connect, чтобы пользователь не мог щелкнуть по ним еще раз. Затем программа устанавливает переменную хода, чтобы она указывала, что контроль над игрой находится у клиента. И, наконец, ход заканчивается вызовом функции завершения хода. Это переводит сервер в режим приема, чтобы он мог получить сообщение о завершении хода от клиента. Все эти действия показаны на рис. 14.16.

Рис. 14.16. Ход выполнения функции vHost()

Функция vConnect()

Функция vConnect() вызывается, когда игрок щелкает по кнопке Connect. Вот как выглядит ее код:

Код подключения очень похож на тот, который я показывал вам в примере подключения к веб-серверу. Клиент сперва получает адрес сервера, а затем пытается установить соединение с ним. Как только соединение успешно установлено, клиент убирает кнопки Connect и Host и отображает новую кнопку Turn Done. В этот момент клиенту дается время, чтобы он мог сделать свой ход. Ход выполнения функции показан на рис. 14.17.

Рис. 14.17. Ход выполнения функции vConnect()

Функция vTurnDone()

Функция завершения хода выполняет две различных задачи. Если сейчас ваш ход, она отправляет сообщение о завершении хода другому игроку и ждет получения сообщения. Если сейчас ход другого игрока, функция ждет, пока он не завершит свой ход. Ход выполнения функции показан на рис. 14.18.

Рис. 14.18. Ход выполнения функции vTurnDone()

Хотя блок-схема и выглядит запутанной, сам код не слишком сложен. Большая его часть занимается обработкой сообщений от окна. Если ее отбросить, оставшийся код будет выглядеть примерно так:

Если вы сравните приведенный выше код с тем, который находится в файле main.cpp , то увидите что здесь код значительно короче. Я удалил из него текстовые сообщения, чтобы вам проще было увидеть, что происходит.

Функция vSendTurnMessage()

Когда приходит время отправлять сообщение о завершении хода, вызывается функция отправки сообщений. Ее код выглядит так:

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

Функция vReceiveTurnMessage()

Когда вы ждете получения хода от другого игрока, работает функция приема сообщения о ходе. Она сидит и ждет пока пакет с данными хода не придет по проводам. Как только прибывает пакет, устанавливается флаг хода и отображается кнопка Turn Done. Вот как выглядит код, выполняющий эти задачи:

В функции приема я вызываю функцию recv для приема пакета от другого игрока. Как только пакет пришел, код устанавливает флаг хода и создает кнопку Turn Done. Вот и все об отправке и получении пакетов!

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

Установка KeepAlive опции для Windows сокетов

Данный код работает без ошибок, но уведомления в виде msgbox’а при отключении удалённого компьютера от сети я дождаться не могу (в течении заданной секунды, да и вообще никогда). Подскажите, в чём причина?

1 ответ 1

Решение состоит в отказе от нативной прослойки в виде dll, т.к. всё достаточно хорошо реализуется средствами самого C# :)

socket.SetSocketOption результата не даст, т.к. KeepAlive опция включена по-умолчанию. Интервал между пробами составляет порядка 2 часов. Чтобы понизить это смешно огромное время нужно настроить опцию. Причём на обеих сторонах соединения (желательно одинаково).

Настройка выполняется через socket.IOControl . Как сделать это есть ответ здесь. Так же могу предложить хорошую статью по этой теме (там же есть рабочий пример на C++): https://rsdn.org/article/net/keep_alive.xml

Теперь, когда после подключения опция настроена, мы можем спокойно работать. Если удалённая сторона внезапно отключится, мы по истечению заданного нами таймаута на попытках операций с сокетом ( Receive , Send ) будем получать исключения.

Сокеты

Класс Socket

В основе межсетевых взаимодействий по протоколам TCP и UDP лежат сокеты. В .NET сокеты представлены классом System.NET.Sockets.Socket , который предоставляет низкоуровневый интерфейс для приема и отправки сообщений по сети.

Рассмотрим основные свойства данного класса:

AddressFamily : возвращает все адреса, используемые сокетом. Данное свойство представляет одно из значений, определенных в одноименном перечислении AddressFamily . Перечисление содержит 18 различных значений, наиболее используемые:

InterNetwork : адрес по протоколу IPv4

InterNetworkV6 : адрес по протоколу IPv6

Ipx : адрес IPX или SPX

NetBios : адрес NetBios

Available : возвращает объем данных, которые доступны для чтения

Connected : возвращает true, если сокет подключен к удаленному хосту

LocalEndPoint : возвращает локальную точку, по которой запущен сокет и по которой он принимает данные

ProtocolType : возвращает одно из значений перечисления ProtocolType , представляющее используемый сокетом протокол. Есть следующие возможные значения:

IPSecAuthenticationHeader (Заголовок IPv6 AH)

IPSecEncapsulatingSecurityPayload (Заголовок IPv6 ESP)

IPv6DestinationOptions (Заголовок IPv6 Destination Options)

IPv6FragmentHeader (Заголовок IPv6 Fragment)

IPv6HopByHopOptions (Заголовок IPv6 Hop by Hop Options)

IPv6NoNextHeader (Заголовок IPv6 No next)

IPv6RoutingHeader (Заголовок IPv6 Routing)

Unknown (неизвестный протокол)

Unspecified (неуказанный протокол)

Каждое значение представляет соответствующий протокол, но наиболее используемыми являются Tcp и Udp.

RemoteEndPoint : возвращает адрес удаленного хоста, к которому подключен сокет

SocketType : возвращает тип сокета. Представляет одно из значений из перечисления SocketType :

Dgram : сокет будет получать и отправлять дейтаграммы по протоколу Udp. Данный тип сокета работает в связке с типом протокола — Udp и значением AddressFamily.InterNetwork

Raw : сокет имеет доступ к нижележащему протоколу транспортного уровня и может использовать для передачи сообщений такие протоколы, как ICMP и IGMP

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

Seqpacket : обеспечивает надежную двустороннюю передачу данных с установкой постоянного подключения

Stream : обеспечивает надежную двустороннюю передачу данных с установкой постоянного подключения. Для связи используется протокол TCP, поэтому этот тип сокета используется в паре с типом протокола Tcp и значением AddressFamily.InterNetwork

Unknown : адрес NetBios

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

Или сокет, использующий протокол Udp:

Таким образом, при создании сокета мы можем указывать разные комбинации протоколов, типов сокета, значений из перечисления AddressFamily. Однако в то же время не все комбинации являются корректными. Так, для работы через протокол Tcp, нам надо обязательно указать параметры: AddressFamily.InterNetwork, SocketType.Stream и ProtocolType.Tcp. Для Udp набор параметров будет другим: AddressFamily.InterNetwork, SocketType.Dgram и ProtocolType.Udp. Для других протоколов набор значений будет отличаться. Поэтому использование сокетов может потребовать некоторого знания принципов работы отдельных протоколов. Хотя в отношении Tcp и Udp все относительно просто.

Общий принцип работы сокетов

При работе с сокетами вне зависимости от выбранных протоколов мы будем опираться на методы класса Socket:

Accept() : создает новый объект Socket для обработки входящего подключения

Bind() : связывает объект Socket с локальной конечной точкой

Close() : закрывает сокет

Connect() : устанавливает соединение с удаленным хостом

Listen() : начинает прослушивание входящих запросов

Poll() : определяет состояние сокета

Receive() : получает данные

Send() : отправляет данные

Shutdown() : блокирует на сокете прием и отправку данных

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

При применении протокола, который требует установление соединения, например, TCP, сервер должен вызвать метод Bind для установки точки для прослушивания входящих подключений и затем запустить прослушивание подключений с помощью метода Listen. Далее с помощью метода Accept можно получить входящие запросы на подключение в виде объекта Socket, который используется для взаимодействия с удаленным узла. У полученного объекта Socket вызываются методы Send и Receive соответственно для отправки и получения данных. Если необходимо подключиться к серверу, то вызывается метод Connect. Для обмена данными с сервером также применяются методы Send или Receive.

Если применяется протокол, для которого не требуется установление соединения, например, UDP, то после вызова метода Bind не надо вызывать метод Listen. И в этом случае для приема данных используется метод ReceiveFrom, а для отправки данных — метод SendTo.

Работа с сокетами. Создание сокета сервера

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

18.11.2011, 11:50

Считывание ответа сервера из сокета
Всем добрый вечер! Недавно начал работать с сокетами и почти сразу столкнулся с проблемой — не.

работа с сокетами
работаю с сокетамим, нашёл в сети пример работы,благо таких много, суть примера между сервером и.

Работа с Сокетами
Добрый день или вечер! Прошу помощи Зависает сервер при подключении клиента до момента.

Работа с сокетами
есть код void __fastcall TForm1::Button1Click(TObject *Sender) < ClientSocket1->Host =.

Работа с сокетами
как вырубить локальный клиент?

Пример работы с сокетами (socket) для windows

Раздел предназначен для публикации различных исходников и программных решений (в виде исходных текстов), которые Вы считаете достойными внимания и/или интересными. Язык исходника значения не имеет. Это может быть C/C++, Pascal, Perl, PHP, C#, Foth, Prolog или любой другой существующий язык программирования. Единственный момент – в названии темы этот язык должен быть указан. Например, «[C++] Представление чисел в римской записи». Сам исходный текст должен содержаться в первом посте темы. Если исходник занимает не больше одного-двух экранов, то допустимо его публикация непосредственно в посте. Иначе исходный текст должен быть прикреплен к посту в виде архива. Кроме того, первый пост должен содержать:

— Информацию о платформе/компиляторе, для которых предназначен исходный текст (если эта информация существенна)
— Ссылку на оригинал и автора (если публикуется чужой исходный текст)
— Максимально подробное описание – какую задачу решает опубликованный исходный текст, и чем он интересен.

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

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

Ключевые слова: WinSock, WinSock2, Sockets, Win, Windows, WinApi, Win32, примеры работы с сокетами, сокеты, асинхронные сокеты, мультикастинг, TCP, UDP, IGMP, сетевые протоколы, C++, Visual C++

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

Реализована работа с TCP, UDP, IGMP протоколами.

Пример работы с UDP протоколом, правда все в одном приложении и сендер и ресивер, но легко дробится на два, примеры работы с другими протоколами с исп. данных классо приведы немного позже:

cout Socket — работа с сокетом, создание, привязка и т.д.
TCPSocket — реализует запись данных в сокет (посылка данных) специфичную для TCP
UDPSocket — реализует запись данных в сокет (посылка данных) специфичную для UDP и специфичный коннект для UDP
MCSocket — реализует специфику мультикастинга, а именно создание, настройка сокета и присоединение к группе, а также посылку данных в группу
SocketHandler — обработка сетевых событий
UDPServer — UDP-сервер, т.е. UDP сокет для отправки приема данных, т.е. с биндом, а для просто отправки данных без бинда модно исп. UDPSocket
MCServer — специфика для работы в мультикаст группе

P.S. Сподвигнут на написание классцов очередной темой о сокетах тут , спдвиг на сие zss , за что ему спасибо, давно хотел что-то подобное написать, но все никак не мог собраться

Илон Маск рекомендует:  Что такое код clearviewport

Примеры и развитие либы будет немного позже постараюсь .

P.P.S. Особо не тестировал может есть баги, нашедшим, а мож и предложившим решение, буду очень признателен

Далее на основе приведенного TCP клиента пишем маленькую обертку для отправки электронных писем:

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

Недостаток текущего кода — минимальная проверка ошибок. А проверка ошибок возвращаемых сенрвером отсутсвует полностью, но цеж пример а так все что было выполнено методом Execute результат можног проверить и т.д. Описание ошибок и более полное описание протокола SMTP можно глянуть тут

Вопрос один. Зачем тут классы7 Зачем исключения? По ключевым словам должна быть статья о winsock, а сюда примешивается половина сложных для новичков языковых возможностей, зачем? Чтоб разобраться в сокетах сложно было? И сначала надо было прочитать книжку по С/C++ ? Мода какая-то странная пошла все в классы оборачивать, я представляю как потом отладчиком это будет отлаживать приятно.
Главное, как ни оборачивай — возможности не расширятся. Как ни крути, сокеты остаются сокетами и больше, чем они могут, из них не вынешь.

Я смотрю, ты в крестовый поход против ЯВУ пошел.

вот всё, что новичку нужно написать, чтобы отправить письмо. Покажи-ка код, который ему нужно написать на C, чтобы достить того же самого — там и посмотрим, что сложнее.

Нормальная мода — классом проще и понятней пользоваться, чем сырым WinAPI.

Для тебя расширение возможностей — единственный критерий качества кода? Тогда в данном конктретном случае тебе и сокетов не нужно — переходи в ядро разговаривай непосредственно с сетевухой на её языке — вот где море возможностей..

BlackEmperor: что это за классы:

Sockets::TCPSocket, Sockets::SocketHandler — классы из библиотеки, приведенной в самом первом посте этой темы! И естественно ничего о них MSDN не знает

P.S. см. аттач первого поста

От этого и появляются новички, разбирающиеся только в готовых классах и абсолютно не понимающие что они делают, ни связи с api, ни знание системы, ничего вообще. Только не надо говорить что это не важно. (размышление: скоро нам микрософт сделает язык и к нему студию, в которой вообще ничего знать не надо будет — пишешь «хачу прогу с сокитами» — и тебе такая делается. Да собственно, почему «скоро»? Есть уже — C#)
Классы — действительно удобно, с этим не поспоришь. А вот оборачивать в них все подряд, что под руку попадется — простейшие API и т.п., засовывая туда ещё исключения какие-то, push_back’и, и т.п. — просто только искуственно затруднять все. Я ни в коем случае не являюсь нигилистом или любителем писать hex-кодами в блокноте ради выпендрежа, просто все пытаюсь вдуматься в некоторые технологии и понимаю, что как ни крути — толку от них нет вообще.
Тебе то конечно норм, ты во всем шаришь а и так, а вот людям некоторым, помоему, от таких вариантов написания сетевых прог только хуже в плане развития.

От этого и появляются новички, разбирающиеся только в готовых классах и абсолютно не понимающие что они делают, ни связи с api, ни знание системы, ничего вообще. Только не надо говорить что это не важно. (размышление: скоро нам микрософт сделает язык и к нему студию, в которой вообще ничего знать не надо будет — пишешь «хачу прогу с сокитами» — и тебе такая делается. Да собственно, почему «скоро»? Есть уже — C#)
Классы — действительно удобно, с этим не поспоришь. А вот оборачивать в них все подряд, что под руку попадется — простейшие API и т.п., засовывая туда ещё исключения какие-то, push_back’и, и т.п. — просто только искуственно затруднять все. Я ни в коем случае не являюсь нигилистом или любителем писать hex-кодами в блокноте ради выпендрежа, просто все пытаюсь вдуматься в некоторые технологии и понимаю, что как ни крути — толку от них нет вообще.
Тебе то конечно норм, ты во всем шаришь а и так, а вот людям некоторым, помоему, от таких вариантов написания сетевых прог только хуже в плане развития.

Не хочу, показаться грубым, но не знание языка не освобождает от ответственности
Я не говорю что являюсь гуру в C++, далеко мне до этого, да и реально кто б мог сказать «Я гуру» оправданно думаю мало (понтуются многие ). Как было на предыдущей моей работе, часто народ любил стебаться фразой «Ну кто тут знает C++» (хотя вся контора вся писала на плюсах, и разработчиков был не один десяток . )

А теперь по делу.

Предположим что не хочется копаться во всех обертках, чудесно берем примеры на чистом C и смотри их. Так есть замечательная книга «Программирование в сетях Windows» (вродь так называется), книга и в правду хороша, мне понравилась, но примеры к ней написаны в процедурном стиле и кучей структур глобалюк и т.д., в общем так реально ни одним примером и не воспользовался, гораздо более проще было прочесть очередную главу и написать какую-нить обертку, а ее потом заюзать. Ну кому как, может у кого-то иной подход.
Можно попробовать взять готовую обертку, поюзать ее получить результат (высокоуровневый), а потом, если есть желание, копать вглубь и добраться до апи и как оно работает, мож кто-то капнет и до электрических сигналов в сети и посидит не в дебагере, а уже с осциллографом чур я пас тут , но если копать с другой стороны, скажем когда все неизвестно и верхний уровень задачи и ее более нижние, то придется поболее времени потратить на то чтоб понять как оно все работает на всех уровнях и сразу, а при написании и юзании на более низкоуровневого апи (которое пока еще не освоено) придется не мало провести времени на отладке того чтож не работает, написанное решение более высокоуровневой задачи или что-то накосячил с вызовами более низкоуровневого апи.

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

По поводу push_back’ов и еже с ними. Это все от стандартной библиотеки, можно ее не использовать, написать свой код контейнеров и т.д., но, боюсь, тогда раздадутся возгласы типа: «Как много постороннего кода, что до кода решающего реальную задачу не добраться!». Почему б не взглянуть в справочник по языку, какую-нить книжку или просто MSDN и посмотреть что это?

Не надо путать C++ & C# разные языки, призванные решать разные классы задач!

Боюсь не доживу до того момента когда будет

Албанский еще не скоро станет стандартом программирования и экспериментальных версий компиляторов пока тож не видел

Не надо заявлять, что если не понятны языковые возможности, то так делать нельзя. Упаси вас бог, что-то подобное толкать на собеседованиях в более менее серьезные конторы! Форум расчитан на то что люди чего не знают спрашивают и получают знания и ими пользуются. Любое апи можно достаточно быстро выучить, при возникновении необходимости в этом, кроме того разные апи по большей части, имеют срок своей «жизни» куда более маленький чем язык, делайте выводы
Ну и на последок никто не заставляет пользоваться классами, предложенными в данной теме, не нравится пишите сами, с нами результатами поделитесь, может потом кому-то пригодиться, хотите упростить себе жизнь, возьмите это и / или подобное решение, что не понятно задавайте вопросы, ответим, на это форумы и созданы.

Сокеты Windows

Winsock API разрабатывался как расширение Berkley Sockets API для среды Windows и поэтому поддерживается всеми системами Windows. К преимуществам Winsock можно отнести следующее:

• Перенос уже имеющегося кода, написанного для Berkeley Sockets API, осуществляется непосредственно.

• Системы Windows легко встраиваются в сети, использующие как версию IPv4 протокола TCP/IP, так и постепенно распространяющуюся версию IPv6. Помимо всего остального, версия IPv6 допускает использование более длинных IP-адресов, преодолевая существующий 4-байтовый адресный барьер версии IPv4.

• Сокеты могут использоваться совместно с перекрывающимся вводом/выводом Windows (глава 14), что, помимо всего прочего, обеспечивает возможность масштабирования серверов при увеличении количества активных клиентов.

• Сокеты можно рассматривать как дескрипторы (типа HANDLE) файлов при использовании функций ReadFile и WriteFile и, с некоторыми ограничениями, при использовании других функций, точно так же, как в качестве дескрипторов файлов сокеты применяются в UNIX. Эта возможность оказывается удобной в тех случаях, когда требуется использование асинхронного ввода/вывода и портов завершения ввода/вывода.

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

Похожие главы из других книг

7.2.6.5. Сокеты

7.2.6.5. Сокеты Сокеты (sockets) были разработаны в BSD-ветви Unix как способ инкапсуляции доступа к сетям данных. Две программы, осуществляющие обмен данными через сокет, обычно используют двунаправленный поток байтов (существуют и другие режимы сокетов и методы передачи, но они

7.2.6.5. Сокеты

7.2.6.5. Сокеты Сокеты (sockets) были разработаны в BSD-ветви Unix как способ инкапсуляции доступа к сетям данных. Две программы, осуществляющие обмен данными через сокет, обычно используют двунаправленный поток байтов (существуют и другие режимы сокетов и методы передачи, но они

Сокеты Windows

Сокеты Windows Winsock API разрабатывался как расширение Berkley Sockets API для среды Windows и поэтому поддерживается всеми системами Windows. К преимуществам Winsock можно отнести следующее:• Перенос уже имеющегося кода, написанного для Berkeley Sockets API, осуществляется непосредственно.• Системы

Перекрывающиеся сокеты

Перекрывающиеся сокеты Одним из наиболее важных нововведений в Windows Sockets 2.0 (глава 12) является стандартизация перекрывающегося ввода/вывода. В частности, сокеты уже не создаются автоматически как дескрипторы файлов с перекрытием. Функция socket создает неперекрывающийся

2.1. Стандартные сокеты

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

27.3.10. Сигналы и сокеты

27.3.10. Сигналы и сокеты С сокетами связаны три сигнала:? SIGIO — сокет готов к вводу/выводу. Сигнал посылается процессу, который связан с сокетом;? SIGURG — сокет получил экспресс-данные (мы их использовать не будем, поэтому особо останавливаться на них нет смысла);? SIGPIPE — запись

5.5. Сокеты

5.5.4. Локальные сокеты

5.5.4. Локальные сокеты Сокеты, соединяющие процессы в пределах одного компьютера, работают в локальном пространстве имен (PF_LOCAL или PF_UNIX, это синонимы). Такие сокеты называются локальными или UNIX-сокетами. Их адресами являются имена файлов, указываемые только при создании

5.5.6. Internet-сокеты

5.5.6. Internet-сокеты UNIX-сокеты используются для организации взаимодействия двух процессов, выполняющихся на одном компьютере. С другой стороны. Internet-сокеты позволяют соединять между собой процессы, работающие на разных компьютерах.Пространству имен Internet соответствует

Сокеты

Сокеты Сокеты предназначены для взаимодействия между процессами. Интерфейс сокетов часто используется для доступа к сети TCP/IP. В системах, ветви BSD UNIX на базе сокетов реализована система межпроцессного взаимодействия, с помощью которой работают многие системные сервисы,

Часть 2 Элементарные сокеты

Часть 2 Элементарные сокеты

Глава 3 Введение в сокеты

Глава 3 Введение в сокеты 3.1. Введение Эта глава начинается с описания программного интерфейса приложения (API) сокетов. Мы начнем со структур адресов сокетов, которые будут встречаться почти в каждом примере на протяжении всей книги. Эти структуры можно передавать в двух

Сигнал SIGIO и сокеты UDP

Сигнал SIGIO и сокеты UDP Использовать ввод-вывод, управляемый сигналом, с сокетами UDP довольно легко. Сигнал генерируется в следующих случаях:? на сокет прибывает дейтаграмма;? на сокете возникает асинхронная ошибка.Таким образом, когда мы перехватываем сигнал SIGIO для

Сигнал SIGIO и сокеты TCP

Сигнал SIGIO и сокеты TCP К сожалению, использовать управляемый сигналом ввод-вывод для сокетов TCP почти бесполезно. Проблема состоит в том, что сигнал генерируется слишком часто, а само по себе возникновение сигнала не позволяет выяснить, что произошло. Как отмечается в [128, с.

Глава 28 Символьные сокеты

Глава 28 Символьные сокеты 28.1. Введение Символьные, или неструктурированные, сокеты (raw sockets) обеспечивают три возможности, не предоставляемые обычными сокетами TCP и UDP.1. Символьные сокеты позволяют читать и записывать пакеты ICMPv4, IGMPv4 и ICMPv6. Например, программа ping посылает

Веб-сервер на C++ и сокетах

Создадим HTTP-сервер, который обрабатывает запросы браузера и возвращает ответ в виде HTML-страницы.

Введение в HTTP

Для начала разберемся, что из себя представляет HTTP. Это текстовый протокол для обмена данными между браузером и веб-сервером.

Пример HTTP-запроса:

Первая строка передает метод запроса, идентификатор ресурса (URI) и версию HTTP-протокола. Затем перечисляются заголовки запроса, в которых браузер передает имя хоста, поддерживаемые кодировки, cookie и другие служебные параметры. После каждого заголовка ставится символ переноса строки \r\n .

У некоторых запросов есть тело. Когда отправляется форма методом POST, в теле запроса передаются значения полей этой формы.

Тело запроса отделяется от заголовков одной пустой строкой. Заголовок «Content-Type» говорит серверу, в каком формате закодировано тело запроса. По умолчанию, в HTML-форме данные кодируются методом «application/x-www-form-urlencoded».

Иногда необходимо передать данные в другом формате. Например, при загрузке файлов на сервер, бинарные данные кодируются методом «multipart/form-data».

Сервер обрабатывает запрос клиента и возвращает ответ.

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

В первой строке ответа передается версия протокола и статус ответа. Для успешных запросов обычно используется статус «200 OK». Если ресурс не найден на сервере, возвращается «404 Not Found».

Тело ответа так же, как и у запроса, отделяется от заголовков одной пустой строкой.

Полная спецификации протокола HTTP описывается в стандарте rfc-2068. По понятным причинам, мы не будем реализовывать все возможности протокола в рамках этого материала. Достаточно реализовать поддержку работы с заголовками запроса и ответа, получение метода запроса, версии протокола и URL-адреса.

Что будет делать сервер?

Сервер будет принимать запросы клиентов, парсить заголовки и тело запроса, и возвращать тестовую HTML-страничку, на которой отображены данные запроса клиента (запрошенный URL, метод запроса, cookie и другие заголовки).

О сокетах

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

В этом материале мы будем работать с виндовой реализацией сокетов, которая находится в заголовочном файле . В Unix-подобных ОС принцип работы с сокетами такой же, только отличается API. Вы можете подробнее почитать о сокетах Беркли, которые используются в GNU/Linux.

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

Создадим сокет с помощью функции socket , которая находится в заголовочном файле . Для работы с IP-адресами нам понадобится заголовочный файл .

Мы подготовили все данные, которые необходимо для создания сокета и создали сам сокет. Функция socket возвращает целочисленное значение файлового дескриптора, который выделен операционной системой под сокет.

Привязка сокета к адресу (bind)

Следующим шагом, нам необходимо привязать IP-адрес к сокету, чтобы он мог принимать входящие соединения. Для привязки конкретного адреса к сокету используется фукнция bind . Она принимает целочисленный идентификатор файлового дескриптора сокета, адрес (поле ai_addr из структуры addrinfo ) и размер адреса в байтах (используется для поддержки IPv6).

Подготовка сокета к принятию входящих соединений (listen)

Подготовим сокет к принятию входящих соединений от клиентов. Это делается с помощью функции listen . Она принимает дескриптор слушающего сокета и максимальное количество одновременных соединений.

В случае ошибки, функция listen возращает значение константы SOCKET_ERROR . При успешном выполнении она вернет 0.

В константе SOMAXCONN хранится максимально возможное число одновременных TCP-соединений. Это ограничение работает на уровне ядра ОС.

Ожидание входящего соединения (accept)

Функция accept ожидает запрос на установку TCP-соединения от удаленного хоста. В качестве аргумента ей передается дескриптор слушающего сокета.

При успешной установке TCP-соединения, для него создается новый сокет. Функция accept возвращает дескриптор этого сокета. Если произошла ошибка соединения, то возвращается значение INVALID_SOCKET .

Получение запроса и отправка ответа

После установки соединение с сервером, браузер отправляет HTTP-запрос. Мы получаем содержимое запроса через функцию recv . Она принимает дескриптор TCP-соединения (в нашем случае это client_socket ), указатель на буфер для сохранения полученных данных, размер буфера в байтах и дополнительные флаги (которые сейчас нас не интересуют).

При успешном выполнении функция recv вернет размер полученных данных. В случае ошибки возвращается значение SOCKET_ERROR . Если соединение было закрыто клиентом, то возвращается 0.

Мы создадим буфер размером 1024 байта для сохранения HTTP-запроса.

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

В случае ошибки, функция возвращает значение SOCKET_ERROR . В случае успеха — количество переданных байт.

Попробуем скомпилировать программу, не забыв предварительно завершить функцию main .

Если скомпилировать и запустить программу, то окно консоли «подвиснет» в ожидании запроса на установление TCP-соединения. Откройте в браузере адрес http://127.0.0.1:8000/. Сервер вернет ответ, как на рисунке ниже и завершит работу.

Последовательная обработка запросов

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

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

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

Примечание: если вы используете MinGW в Windows, то библиотеку Ws2_32.lib нужно вручную прописать в настройках линковщика.

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

Сокет´ (socket) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться на одном компьютере или на различных компьютерах, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.

Интерфейс сокетов впервые появился в BSD Unix. Программный интерфейс сокетов описан в стандарте POSIX и в той или иной мере поддерживается всеми современными операционными системами.

5.1. Использование классических блокирующих сокетов

5.1.1. Алгоритм работы сервера и клиента

С установлением соединения. Порядок использования блокирующих сокетов с установлением соединения:

На стороне сервера:

1. Инициализировать библиотеку Winsock ( WSAStartup , только для платформы Windows).

2. Создать сокет ( socket ).

3. Связать сокет ( bind ).

4. Перевести его в слушающий режим ( listen ).

5. Принять запрос на соединение ( accept ).

6. Получить ( recv ) или отправить ( send ) данные.

7. Отключить сокет ( shutdown ).

8. Закрыть сокет ( close , для Windows — closesocket ).

9. Закрыть библиотеку Winsock ( WSACleanup , только для платформы Windows).

На стороне клиента:

1. Инициализировать библиотеку Winsock ( WSAStartup , только для платформы Windows)

2. Создать сокет ( socket ).

3. Послать запрос на соединение ( connect ).

4. Отправить ( send ) или получить ( recv ) данные.

5. Отключить сокет ( shutdown ).

6. Закрыть сокет ( close , для Windows — closesocket ).

7. Закрыть библиотеку Winsock ( WSACleanup , только для платформы Windows).

Без установления соединения. Порядок использования блокирующих сокетов без установления соединения (одинаково для сервера и клиента):

1. Инициализировать библиотеку Winsock ( WSAStartup , только для платформы Windows).

Ю.В. Земсков. Вычислительные сети. Версия 0.20. — Санкт-Петербургский гос. университет гражданской авиации , 2012

2. Создать сокет ( socket ).

3. Связать сокет ( bind ).

4. Получить ( recvfrom ) или отправить ( sendto ) данные.

5. Закрыть сокет ( close , для Windows — closesocket ).

6. Закрыть библиотеку Winsock ( WSACleanup , только для платформы Windows).

5.1.2. Функции API сокетов

Для использования сокетов в системе Windows необходимо подключать заголовочный файл , в Linux — . Если приложение разрабатывается в системе Microsoft Visual C++, то к проекту надо подключить библиотеку ws2_32.lib . Для этого надо выполнить команду главного меню í Project í Settings Link Category: s General

и дописать имя библиотечного файла в поле « Object/library modules » (рис. 5.1 ).

Рис. 5.1. Подключение библиотеки ws2_32.lib в Microsoft Visual C++

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

Илон Маск рекомендует:  Атрибут marginheight в HTML

Создание серверного или клиентского сокета. Дескриптор (описатель) сокета — это переменная типа SOCKET . Сокет создаётся с помощью функции

SOCKET socket(int domain, int type, int protocol);

Возвращаемое значение: дескриптор сокета в случае успеха; −1 (Linux) или INVALID_SOCKET (Windows) — ошибка. Входной параметр domain — константа, указывающая, какой домен нужен сокету. Обычно используются домены AF_INET (т. е. Internet) и AF_LOCAL (применяется для межпроцессного взаимодействия (IPC) на одной и той же машине).

Ю.В. Земсков. Вычислительные сети. Версия 0.20. — Санкт-Петербургский гос. университет гражданской авиации , 2012

С помощью параметра type задаётся тип создаваемого сокета. Чаще встречаются следующие значения:

∙ SOCK_STREAM — обеспечивают надёжный дуплексный протокол на основе установления логического соединения. Если говорится о семействе протоколов TCP/IP, то это TCP;

∙ SOCK_DGRAM — обеспечивают ненадежный сервис доставки датаграмм. В рамках TCP/IP это протокол UDP;

∙ SOCK_RAW — предоставляют доступ к некоторым датаграммам на уровне протокола IP. Они используются в особых случаях, например для просмотра всех ICMP-сообщений.

Параметр protocol показывает, какой протокол следует использовать с данным сокетом. В контексте TCP/IP он обычно неявно определяется типом сокета, поэтому в качестве значения задают 0 . Иногда, например, в случае rawсокетов, имеется несколько возможных протоколов, тогда данный параметр необходимо задавать явно.

Система не освобождает ресурсы, выделенные при вызове socket() , пока не произойдет вызова closesocket() . Каждый вызов socket() должен иметь соответствующий вызов closesocket() во всех возможных путях исполнения. Результатом выполнения системного вызова closesocket() является только обращение к интерфейсу для закрытия сокета, а не закрытие самого сокета. Другими словаи, это всего лишь команда для операционной системы закрыть сокет, а само освобождение ресурсов будет выполнено системой позже, в соответствии с алгоритмами её работы.

Подключение клиента к серверу. Соединение с удалённым сокетом устанавливается с помощью функции

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

Возвращаемое значение: 0 — нормально; −1 (Linux) или не 0 (Windows) — ошибка. Параметр s — дескриптор сокета, который получен в результате вызова функции socket() . Параметр peer указывает на структуру, в которой хранится адрес удаленного хоста и некоторая дополнительная информация. Для домена AF_INET это структура типа sockaddr_in . Параметр peer_len содержит размер структуры (в байтах), на которую указывает peer .

После установления соединения можно передавать данные.

Передача и приём данных. В системе Linux передача и приём информации выполняется с помощью функций read() и write() , которым передаётся дескриптор сокета. В системе Windows используются функции recv() (приём) и send() (передача данных):

int recv(SOCKET s, void *buf,

Ю.В. Земсков. Вычислительные сети. Версия 0.20. — Санкт-Петербургский гос. университет гражданской авиации , 2012

size_t len, int flags); int send(SOCKET s, const void *buf,

size_t len, int flags);

Возвращаемое значение: число принятых или переданных байтов в случае успеха; −1 в случае ошибки.

Параметры buf и len — адрес буфера для приёма или отправки информации и его длина. Значение параметра flags зависит от системы, но и Linux,

и Windows поддерживают следующие флаги:

∙ MSG_OOB — следует послать или принять срочные данные;

∙ MSG_PEEK — используется для просмотра поступивших данных без их удаления из приёмного буфера. После возврата из системного вызова данные еще могут быть получены при последующем вызове read()

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

При работе с UDP нужны еще системные вызовы recvfrom() и sendto() . Они очень похожи на recv() и send() , но позволяют при отправке датаграммы задать адрес назначения, а при приёме — получить адрес источника:

int recvfrom(SOCKET s, void *buf, size_t len, int flags, struct sockaddr *from, int *fromlen);

int sendto(SOCKET s, const void *buf, size_t len, int flags, const struct sockaddr *to, int tolen);

Возвращаемое значение: число принятых или переданных байтов в случае успеха; −1 при ошибке.

Первые четыре параметра: s , buf , len и flags — такие же, как в вызовах recv() и send() . Параметр from в вызове recvfrom() указывает на структуру, в которую ядро помещает адрес источника пришедшей датаграммы. Длина этого адреса хранится в целом числе, на которое указывает параметр fromlen . Обратите внимание, что fromlen — это указатель на целое. Аналогично параметр to в вызове sendto() указывает на адрес структуры, содержащей адреса назначения датаграммы, а параметр tolen — длина этого адреса. Заметьте, что to — это целое, а не указатель.

Функции send() и recv() не являются атомарными и нет никакой rарантии, что затребованные данные будут действительно отправлены или получены в результате одного вызова этих функций. Приходится проверять возвращаемое значение (фактическое количество принятых или отправленных байт)

Ю.В. Земсков. Вычислительные сети. Версия 0.20. — Санкт-Петербургский гос. университет гражданской авиации , 2012

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

Связывание серверного сокета. На стороне сервера необходимо привязать адрес интерфейса и номер порта к прослушивающему сокету. Для этого предназначен вызов bind() :

int bind(SOCKET s, const struct sockaddr *name, int namelen);

Возвращаемое значение: 0 — нормально, −1 (Linux) или SOCKET_ERROR (Windows) — ошибка. Параметр s — дескриптор слушающего сокета. С помощью параметров name и namelen передаются порт и сетевой интерфейс, которые нужно прослушивать. Обычно в качестве адреса задается константа INADDR_ANY . Это означает, что будет принято соединение, запрашиваемое по любому интерфейсу. Если хосту с несколькими сетевыми адресами нужно принимать соединения только по одному интерфейсу, то следует указать IP-адрес этого интерфейса. Параметр namelen — длина структуры sockaddr_in .

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

int listen(SOCKET s, int backlog);

Возвращаемое значение: 0 — нормально, −1 (Linux) или SOCKET_ERROR (Windows) — ошибка. Параметр s — дескриптор сокета, который нужно перевести в режим прослушивания. Параметр backlog — максимальное число ожидающих, но еще не принятых соединений. Следует отметить, что это не максимальное число одновременных соединений с данным портом, а лишь максимальное число частично установленных соединений, ожидающих в очереди, пока приложение их примет (описание системного вызова accept() дано ниже). Традиционно значение параметра backlog() — не более пяти соединений, но в современных реализациях, которые должны поддерживать приложения с высокой нагрузкой, например, Web-сервера, оно может быть намного больше. Поэтому, чтобы выяснить его истинное значение, необходимо изучить документацию по конкретной системе. Если задать значение, большее максимально допустимого, то система уменьшит его, не сообщив об ошибке.

Слушающие соединения (listening connections) — это пассивные серверные сокеты, ожидающие клиента. Как только клиент делает новый запрос, сервер

Ю.В. Земсков. Вычислительные сети. Версия 0.20. — Санкт-Петербургский гос. университет гражданской авиации , 2012

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

Приём сервером запроса от клиента на установку соединения. И последний вызов, который будет здесь рассмотрен, — это accept() . Он служит для приёма соединения, ожидающего во входной очереди. После того как соединение принято, его можно использовать для передачи данных, например, с помощью вызовов recv() и send() . В случае успеха accept() возвращает дескриптор нового сокета, по которому и будет происходить обмен данными. Номер локального порта для этого сокета такой же, как и для прослушивающего сокета. Адрес интерфейса, на который поступил запрос о соединении, называется локальным. Адрес и номер порта клиента считаются удаленными.

Обратите внимание, что оба сокета имеют один и тот же номер локального порта. Это нормально, поскольку TCP-соединение полностью определяется четырьмя параметрами: локальным адресом, локальным портом, удалённым адресом и удалённым портом. Поскольку удалённые адрес и порт для этих двух сокетов различны, то ядро может отличить их друг от друга.

int accept(SOCKET s, struct sockaddr *addr, int *addrlen);

Функция accept() блокируется до тех пор, пока от клиента не поступит запрос соединения, после чего она возвращает новый сокет. Возвращаемое значение: дескриптор этого нового сокета в случае успеха; −1 (Linux) или INVALID_SOCKET (Windows) — ошибка.

Параметр s — дескриптор слушающего сокета. Вызов accept() возвращает адрес подключившегося к серверу клиента в структуре sockaddr_in , на которую указывает параметр addr . Целому числу, на которое указывает параметр addrlen , ядро присваивает значение, равное длине этой структуры. Часто нет необходимости знать адрес клиента, тогда в качестве addr и addrlen передаётся NULL .

5.1.3. Пример использования блокирующих TCP-сокетов в однопоточном сервере и клиенте

Рассмотрим пример сервера и клиента Winsock (листинги 2 и 3 ), написанные на языке C (консольные приложения). Здесь клиент соединяется с сервером и посылает ему сообщение, состоящее из пяти символов. Сервер принимает сообщение и выводит его на экран. Сервер является однопоточным приложением, т. е. может одновременно работать только с одним клиентом.

уПЛЕФЩ

уПЛЕФ — ХУФТПКУФЧП ДЧХОБРТБЧМЕООПК УЧСЪЙ, ЛПФПТПЕ НПЦЕФ ЙУРПМШЪПЧБФШУС ДМС ЧЪБЙНПДЕКУФЧЙС У ДТХЗЙН РТПГЕУУПН ОБ ПДОПК Й ФПК ЦЕ НБЫЙОЕ ЙМЙ У РТПГЕУУПН, ЪБРХЭЕООЩН ОБ ДТХЗЙИ НБЫЙОБИ. рТПЗТБННЩ йОФЕТОЕФБ ФБЛЙЕ ЛБЛ Telnet, rlogin, FTP, talk , Й World Wide Web ЙУРПМШЪХАФ УПЛЕФЩ.

оБРТЙНЕТ, НПЦОП РПМХЮЙФШ WWW-УФТБОЙГХ ПФ УЕТЧЕТБ Web, ЙУРПМШЪХС РТПЗТБННХ Telnet , ФБЛ ЛБЛ ПОЙ ПВЕ ЙУРПМШЪХАФ УПЛЕФЩ ДМС УЕФЕЧПЗП ЧЪБЙНПДЕКУФЧЙС. дМС ПФЛТЩФЙС РПДЛМАЮЕОЙС У УЕТЧЕТПН WWW ОБ www.codesourcery.com, ОЕПВИПДЙНП ЙУРПМШЪПЧБФШ telnet www.codesourcery.com 80 . лПОУФБОФБ 80 ПРТЕДЕМСЕФ РПДЛМАЮЕОЙЕ Л Web УЕТЧЕТХ. еУМЙ РПУМЕ ФПЗП, ЛБЛ РПДЛМАЮЕОЙЕ ВХДЕФ ХУФБОПЧМЕОП, РЕТЕДБФШ ЛПНБОДХ get /, ФП Web УЕТЧЕТХ ЮЕТЕЪ УПЛЕФЩ ВХДЕФ ПФРТБЧМЕОП УППВЭЕОЙЕ, ОБ ЛПФПТПЕ ПО ПФЧЕФЙФ, РЕТЕДБЧ ЙУИПДОЩК ФЕЛУФ ДПНБЫОЕК HTML УФТБОЙГЩ Й ЪБФЕН ЪБЛТПЕФ РПДЛМАЮЕОЙЕ.

пУОПЧЩ УПЛЕФПЧ

рТЙ УПЪДБОЙЙ УПЛЕФБ, ОЕПВИПДЙНП ПРТЕДЕМЙФШ ФТЙ РБТБНЕФТБ: УФЙМШ ЧЪБЙНПДЕКУФЧЙС, РТПУФТБОУФЧП ЙНЕО, Й РТФПЛПМ. уФЙМШ ЧЪБЙНПДЕКУФЧЙС ЛПОФТПМЙТХЕФ, ЛБЛ УПЛЕФ ПВТБВБФЩЧБЕФ РЕТЕДБЧБЕНЩЕ ДБООЩЕ, Й ПРТЕДЕМСЕФ ЛПМЙЮЕУФЧП РБТФОЕТПЧ ЧЪБЙНПДЕКУФЧЙС. юЕТЕЪ УПЛЕФЩ ДБООЩЕ РЕТЕДБАФУС ВМПЛБНЙ (РБЛЕФБНЙ). уФЙМШ ЧЪБЙНПДЕКУФЧЙС ПРТЕДЕМСЕФ, ЛБЛ ЬФЙ РБЛЕФЩ ВХДХФ ПВТБВПФБОЩ Й ЛБЛ ПОЙ РЕТЕДБАФУС ПФ ПФРТБЧЙФЕМС Л РПМХЮБФЕМА.

  • уФЙМЙ УПЕДЙОЕОЙС ЗБТБОФЙТХАФ ДПУФБЧЛХ ЧУЕИ РБЛЕФПЧ Ч ФПН РПТСДЛЕ, Ч ЛБЛПН ПОЙ ВЩМЙ ПФРТБЧМЕОЩ. еУМЙ ЧП ЧТЕНС РЕТЕДБЮЙ РБЛЕФЩ ВЩМЙ РПФЕТСОЩ ЙМЙ ДПУФБЧМЕОЩ Ч ОЕРТБЧЙМШОПН РПТСДЛЕ, РПМХЮБФЕМШ БЧФПНБФЙЮЕУЛЙ ПФРТБЧМСЕФ ЪБРТПУ ОБ ЙИ РПЧФПТОХА РЕТЕДБЮХ. уФЙМШ УПЕДЙОЕОЙС ОБРПНЙОБЕФ ФЕМЕЖПООЩК ЪЧПОПЛ: БДТЕУБ ПФРТБЧЙФЕМС Й РПМХЮБФЕМС ЖЙЛУЙТХАФУС Ч ОБЮБМЕ УПЕДЙОЕОЙС, РТЙ ХУФБОПЧЛЕ РПДЛМАЮЕОЙС.
  • уФЙМЙ ДБФБЗТБН ОЕ ЗБТБОФЙТХЕФ ДПУФБЧЛЙ Й РТБЧЙМШОПЗП РПТСДЛБ РТЙВЩФЙС. рБЛЕФЩ НПЗХФ ВЩФШ РПФЕТСОЩ ЙМЙ РЕТЕХРПТСДПЮЕОЩ Ч РХФЙ ЙЪ-ЪБ УЕФЕЧЩИ ПЫЙВПЛ. лБЦДЩК РБЛЕФ ДПМЦЕО ВЩФШ РПНЕЮЕО ЕЗП БДТЕУБФПН, Й ОЕФ ЗБТБОФЙЙ, ЮФП ПО ВХДЕФ ДПУФБЧМЕО. уЙУФЕНБ ЗБТБОФЙТХЕФ ФПМШЛП «НБЛУЙНБМШОЩЕ ХУЙМЙС», РПЬФПНХ РБЛЕФЩ НПЗХФ ЙУЮЕЪОХФШ ЙМЙ РТЙВЩФШ Ч ТБЪМЙЮОПН РПТСДЛЕ. уПЛЕФ УФЙМС ДБФБЗТБНЩ ЧЕДЕФ УЕВС УИПДОП У РПЮФПК. пФРТБЧЙФЕМШ ПРТЕДЕМСЕФ БДТЕУ РПМХЮБФЕМС ДМС ЛБЦДПЗП ЙОДЙЧЙДХБМШОПЗП УППВЭЕОЙС.

рТПУФТБОУФЧП ЙНЕО ПРТЕДЕМСЕФ, ЛБЛ ЪБРЙУБОЩ БДТЕУБ УПЛЕФБ ( socket addresses ). бДТЕУ УПЛЕФБ ЙДЕОФЙЖЙГЙТХЕФ ПДЙО ЛПОЕГ РПДЛМАЮЕОЙС УПЛЕФБ. оБРТЙНЕТ, БДТЕУБ УПЛЕФБ Ч МПЛБМШОПН РТПУФТБОУФЧЕ ЙНЕО СЧМСАФУС ПВЩЮОЩНЙ ЙНЕОБНЙ ЖБКМПЧ. ч РТПУФТБОУФЧЕ ЙНЕО йОФЕТОЕФ БДТЕУ УПЛЕФБ УПУФПЙФ ЙЪ йОФЕТОЕФ БДТЕУБ ( IP БДТЕУ) ЗМБЧОПЗП ЛПНРШАФЕТБ, РТЙУПЕДЙОЕООПЗП Л УЕФЙ Й ОПНЕТБ РПТФБ, ЛПФПТЩК ЙДЕОФЙЖЙГЙТХЕФ УПЛЕФ УТЕДЙ НОПЦЕУФЧБ УПЛЕФПЧ ОБ ФПН ЦЕ ЗМБЧОПН ЛПНРШАФЕТЕ.

рТПФПЛПМ ПРТЕДЕМСЕФ, ЛБЛ РЕТЕДБАФУС ДБООЩЕ. уХЭЕУФЧХАФ УМЕДХАЭЙЕ ЧЙДЩ РТПФПЛПМПЧ: TCP/IP , РЕТЧЙЮОЩЕ УЕФЕЧЩЕ РТПФПЛПМЩ, ЙУРПМШЪХЕНЩЕ йОФЕТОЕФПН; УЕФЕЧПК РТПФПЛПМ AppleTalk ; МПЛБМШОЩК UNIX РТПФПЛПМ ЧЪБЙНПДЕКУФЧЙС. оЕ ЧУЕ ЛПНВЙОБГЙЙ УФЙМЕК, РТПУФТБОУФЧ ЙНЕО Й РТПФПЛПМПЧ РПДДЕТЦЙЧБАФУС.

уЙУФЕНОЩЕ ЧЩЪПЧЩ

чЙДЩ УЙУФЕНОЩИ ЧЩЪПЧПЧ:

  • socket — УПЪДБФШ УПЛЕФ
  • closes — ХОЙЮФПЦЙФШ УПЛЕФ
  • connect — УПЪДБФШ УПЕДЙОЕОЙЕ НЕЦДХ ДЧХНС УПЛЕФБНЙ
  • bind — РТЙЧСЪБФШ УПЛЕФ Л РПТФХ УЕТЧЕТБ
  • listen — ОБУФТПКЛБ УПЛЕФБ ДМС РТЙОСФЙС РПДЛМАЮЕОЙК
  • accept — РТЙОСФШ ЪБРТПУ ОБ УПЕДЙОЕОЙЕ Й УПЪДБФШ УПЛЕФ ДМС РТПГЕУУБ ЧЪБЙНПДЕКУФЧЙС

уПЛЕФЩ РТЕДУФБЧМСАФУС ДЕУЛТЙРФПТБНЙ ЖБКМПЧ.

уПЪДБОЙЕ Й ХОЙЮФПЦЕОЙЕ УПЛЕФПЧ

у РПНПЭША ЖХОЛГЙК socket Й close УПЪДБАФУС Й ХОЙЮФПЦБАФУС УПЛЕФЩ. рТЙ УПЪДБОЙЙ УПЛЕФБ, ОЕПВИПДЙНП ПРТЕДЕМЙФШ ФТЙ РБТБНЕФТБ УПЛЕФБ: РТПУФТБОУФЧП ЙНЕО, УФЙМШ ЧЪБЙНПДЕКУФЧЙС Й РТПФПЛПМ.

дМС ХЛБЪБОЙС РТПУФТБОУФЧБ ЙНЕО ЙУРПМШЪХАФУС ЛПОУФБОФЩ, ОБЮЙОБАЭЙЕУС У PF_ (УПЛТБЭЕОЙЕ «УЕНЕКУФЧП РТПФПЛПМБ»). оБРТЙНЕТ, PF_LOCAL ЙМЙ PF_UNIX ПРТЕДЕМСАФ МПЛБМШОПЕ РТПУФТБОУФЧП ЙНЕО, Й PF_INET ПРТЕДЕМСЕФ йОФЕТОЕФ РТПУФТБОУФЧП ЙНЕО.

чФПТПК РБТБНЕФТ, УФЙМШ ЧЪБЙНПДЕКУФЧЙС, РТЕДУФБЧМСЕФ УПВПК ЛПОУФБОФХ, ОБЮЙОБАЭЙАУС У SOCK_ . SOCK_STREAM ПРЕТЕДЕМСЕФ УФЙМШ ЧЪБЙНПДЕКФУЧЙС УПЕДЙОЕОЙЕ, SOCK_DGRAM — УФЙМШ ДБФБЗТБНЩ.

фТЕФЙК РБТБНЕФТ, РТПФПЛПМ, ПРТЕДЕМСЕФ НЕИБОЙЪН ОЙЦОЕЗП ХТПЧОС ДМС РЕТЕДБЮЙ Й РПМХЮЕОЙС ДБООЩИ. дМС ЛБЦДПК ЛПНВЙОБГЙЙ РТПУФТБОУФЧП ЙНЕО — УФЙМШ ЧЪБЙНПДЕМКУФЧЙС УХЭЕУФЧХЕФ УЧПК РТПФПЛПМ.

дМС ЛБЦДПК РБТЩ УХЭЕУФЧХЕФ МХЮЫЙК РТПФПЛПМ, РПЬФПНХ НПЦОП ХЛБЪБФШ 0, ЮФП УППФЧЕФУЧХЕФ ЬФПНХ РТПФПЛПМХ. еУМЙ ЛПНБОДБ socket ЧЩРПМОЕОБ ХУРЕЫОП, Ч ЛБЮЕУФЧЕ ТЕЪХМШФБФБ ЧПЪЧТБЭБЕФУС ДЕУЛТЙРФПТ ЖБКМБ ДМС УПЛЕФБ. у РПНПЭША ЛПНБОД read Й write , НПЦОП ЮЙФБФШ Й ЪБРЙУЩЧБФШ ДБООЩЕ Ч УПЛЕФ.

чЩЪПЧ connect

дМС УПЪДБОЙС УПЕДЙОЕОЙЕ НЕЦДХ ДЧХНС УПЛЕФБНЙ, ЛМЙЕОФ ЧЩЪЩЧБЕФ connect , РЕТЕДБЧБС БДТЕУ УПЛЕФБ УЕТЧЕТБ ДМС РПДЛМАЮЕОЙС. лМЙЕОФ — РТПГЕУУ, ЙОЙГЙБМЙЪЙТХАЭЙК УПЕДЙОЕОЙЕ, Б УЕТЧЕТ — РТПГЕУУ, ПЦЙДБАЭЙК ТБЪТЕЫЕОЙС УПЕДЙОЕОЙС. лМЙЕОФ РПУЩМБЕФ ЪБРТПУ connect , ЮФПВЩ ЙОЙГЙБМЙЪЙТПЧБФШ УПЕДЙОЕОЙЕ НЕЦДХ МПЛБМШОЩН УПЛЕФПН Й УПЛЕФПН УЕТЧЕТБ, РЕТЕДБООЩН Ч ЛБЮЕУФЧЕ ЧФПТПЗП РБТБНЕФТБ. ч ЛБЮЕУФЧЕ ФТЕФШЕЗП РБТБНЕФТБ РЕТЕДБЕФУС ДМЙОБ, Ч ВБКФБИ, БДТЕУОПК УФТХЛФХТЩ, ОБ ЛПФПТХА ХЛБЪЩЧБЕФ ЧФПТПК РБТБНЕФТ.

пФРТБЧЛБ ДБООЩИ

мАВБС ФЕИОЙЛБ ЪБРЙУЙ Ч ДЕУЛТЙРФПТ ЖБКМБ, НПЦЕФ ЙУРПМШЪПЧБФШУС РТЙ ЪБРЙУЙ Ч УПЛЕФ. жХОЛГЙС send , ПРТЕДЕМЕООБС ДМС ДЕУЛТЙРФПТПЧ ЖБКМПЧ УПЛЕФБ, БОБМПЗЙЮОБ ЖХОЛГЙЙ write У ОЕУЛПМШЛЙНЙ ДПРПМОЙФЕМШОЩНЙ РБТБНЕФТБНЙ.

уЕТЧЕТЩ

гЙЛМ ЦЙЪОЙ УЕТЧЕТБ УПУФПЙФ ЙЪ УПЪДБОЙС УПЛЕФБ, РТЙЧСЪЛЙ УПЛЕФБ Л БДТЕУХ, ЧЩЪПЧБ listen , ТБЪТЕЫБАЭЕЗП УПЕДЙОЕОЙЕ У УПЛЕФПН, ЧЩЪПЧБ accept , РТЙОЙНБАЭЕЗП ЧИПДСЭЙЕ УПЕДЙОЕОЙС, Й ЪБФЕН ЪБЛТЩФЙС УПЛЕФБ. дБООЩЕ ОЕ ЮЙФБАФУС Й ОЕ ЪБРЙУЩЧБАФУС ОЕРПУТЕДУФЧЕООП ЮЕТЕЪ УПЛЕФ УЕТЧЕТБ; ЧНЕУФП ЬФПЗП, ЛБЦДЩК ТБЪ ЛПЗДБ РТПЗТБННБ РТЙОЙНБЕФ ОПЧПЕ УПЕДЙОЕОЙЕ, Linux УПЪДБЕФ ПФДЕМШОЩК УПЛЕФ, ЙУРПМШЪХЕФУС РТЙ РЕТЕДБЮЕ ДБООЩИ РП ЬФПНХ УПЕДЙОЕОЙА. ч ЬФПН ТБЪДЕМЕ ТБУУНБФТЙЧБАФУС ЧЩЪПЧЩ bind, listen Й accept .

у РПНПЭША ЛПНБОДЩ bind БДТЕУ УЕТЧЕТБ ДПМЦЕО ВЩФШ РТЙЧСЪБО Л УПЛЕФХ. рЕТЧЩК РБТБНЕФТ ЛПНБОДЩ — ДЕУЛТЙРФПТ ЖБКМБ УПЛЕФБ. чФПТПК РБТБНЕФТ — ХЛБЪБФЕМШ ОБ УФТХЛФХТХ БДТЕУБ УЕТЧЕТБ; ЖПТНБФ ЛПФПТПЗП ЪБЧЙУЙФ ПФ УЕНЕКУФЧБ БДТЕУБ. фТЕФЙК РБТБНЕФТ — ДМЙОБ УФТХЛФХТЩ БДТЕУБ, Ч ВБКФБИ.

лПЗДБ БДТЕУ УЧСЪБО У УПЛЕФПН УФЙМС УПЕДЙОЕОЙЕ, ОЕПВИПДЙНП ЧЩЪЧБФШ listen , ЮФПВЩ ХЛБЪБФШ, ЮФП ЬФП — УЕТЧЕТ. рЕТЧЩК РБТБНЕФТ ЛПНБОДЩ — ДЕУЛТЙРФПТ ЖБКМБ УПЛЕФБ. чФПТПК РБТБНЕФТ ПРТЕДЕМСЕФ, ДМЙОХ ПЮЕТЕДЙ ПЦЙДБАЭЙИ УПЕДЙОЕОЙК. еУМЙ ПЮЕТЕДШ ЪБРПМОЕОБ, ДПРПМОЙФЕМШОЩЕ УПЕДЙОЕОЙС ВХДХФ ПФЧЕТЗОХФЩ. ьФП ОЕ ПЗТБОЙЮЙЧБЕФ ПВЭЕЕ ЛПМЙЮЕУФЧП УПЕДЙОЕОЙК, ЛПФПТЩЕ УЕТЧЕТ НПЦЕФ ПВТБВПФБФШ; ЬФП ПЗТБОЙЮЙЧБЕФ ФПМШЛП ЮЙУМП ЛМЙЕОФПЧ, РЩФБАЭЙИУС УПЕДЙОЙФШУС Й ОЕ РПМХЮЙЧЫЙИ РПДФЧЕТЦДЕОЙЕ.

у РПНПЭША ЛПНБОДЩ accept УЕТЧЕТ РТЙОЙНБЕФ ЪБРТПУ ОБ УПЕДЙОЕОЙЕ ПФ ЛМЙЕОФБ. рЕТЧЩК РБТБНЕФТ ЧЩЪПЧБ — ДЕУЛТЙРФПТ ЖБКМБ УПЛЕФБ. чФПТПК РБТБНЕФТ ХЛБЪЩЧБЕФ ОБ УФТХЛФХТХ БДТЕУБ УПЛЕФБ, Ч ЛПФПТПК ИТБОЙФУС БДТЕУ ЛМЙЕОФУЛПЗП УПЛЕФБ. фТЕФЙК РБТБНЕФТ — ДМЙОБ, Ч ВБКФБИ, УФТХЛФХТЩ БДТЕУБ УПЛЕФБ. уЕТЧЕТ НПЦЕФ ЙУРПМШЪПЧБФШ БДТЕУ ЛМЙЕОФБ, ЮФПВЩ ПРТЕДЕМЙФШ, ФТЕВХЕФУС МЙ ДЕКУФЧЙФЕМШОП ЧЪБЙНПДЕКУФЧПЧБФШ У ЛМЙЕОФПН.

чЩЪПЧ accept УПЪДБЕФ ОПЧЩК УПЛЕФ ДМС ЧЪБЙНПДЕКУФЧЙС У ЛМЙЕОФПН Й ЧПЪЧТБЭБЕФ УППФЧЕФУФЧХАЭЙК ДЕУЛТЙРФПТ ЖБКМБ. пТЙЗЙОБМШОЩК УПЛЕФ УЕТЧЕТБ РТПДПМЦБЕФ РТЙОЙНБФШ ОПЧЩЕ ЛМЙЕОФУЛЙЕ УПЕДЙОЕОЙС.

дМС ЮФЕОЙС ДБООЩИ ЙЪ УПЛЕФБ, ВЕЪ ХДБМЕОЙС ЙИ ЙЪ ЧИПДОПК ПЮЕТЕДЙ, ЙУРПМШЪХЕФУС ЛПНБОДБ recv . ч ЛБЮЕУФЧЕ РБТБНЕФТПЧ РЕТЕДБАФУС ФЕЦЕ БТЗХНЕОФЩ, ЮФП Й Ч ЛПНБОДЕ read , РМАУ ДПРПМОЙФЕМШОЩК РБТБНЕФТ FLAGS . жМБЗ MSG_PEEK ХЛБЪЩЧБЕФ, ЮФП ДБООЩЕ ДПМЦОЩ ВЩФШ РТПЮЙФБОЩ, ОП ОЕ ХДБМЕОЩ ЙЪ ЧИПДОПК ПЮЕТЕДЙ.

мПЛБМШОЩЕ УПЛЕФЩ

уПЛЕФЩ, РПДЛМАЮБАЭЙЕ РТПГЕУУЩ ОБ ПДОПН ЛПНРШАФЕТЕ НПЗХФ ЙУРПМШЪПЧБФШ МПЛБМШОПЕ РТПУФТБОУФЧП ЙНЕО, РТЕДУФБЧМСАЭЙК УПВПК УЙОПОЙН ДМС PF_LOCAL Й PF_UNIX . пОЙ ОБЪЩЧБАФУС МПЛБМШОЩНЙ УПЛЕФБНЙ ЙМЙ УПЛЕФБНЙ UNIX-ДПНЕОБ. бДТЕУБ ЬФЙИ УПЛЕФПЧ, ПРТЕДЕМСЕНЩЕ ЙНЕОБНЙ ЖБКМПЧ, ЙУРПМШЪХАФУС ФПМШЛП РТЙ УПЪДБОЙЙ УПЕДЙОЕОЙС.

йНС УПЛЕФБ ХЛБЪЩЧБЕФУС Ч УФТХЛФХТЕ sockaddr_un . еУМЙ Ч AF_LOCAL ХУФБОПЧМЕОП РПМЕ sun_family , ЬФП ХЛБЪЩЧБЕФ ОБ ФП, ЮФП БДТУ Ч ДПЛБМШОПН РТПУФТБОУФЧЕ ЙНЕО. рПМЕ Sun_path ХЛБЪЩЧБЕФ, ЮФП ЙУРПМШЪХЕФУС ЙНС ЖБКМБ; НБЛУЙНБМШОБС ДМЙОБ РПМС — 108 ВБКФ. дМС ЧЩЮЙУМЕОЙС ДМЙОЩ struct sockaddr_un ЙУРПМШЪХЕФУС НБЛТПЛПНБОДБ SUN_LEN . нПЦЕФ ЙУРПМШЪПЧБФШУС МАВПЕ ЙНС ЖБКМБ, ОП ДМС РТПГЕУУБ ДПМЦОП ВЩФШ ХУФБОПЧМЕОП РТБЧП ОБ ЪБРЙУШ Ч ЛБФБМПЗ. юФПВ УПЕДЙОЕОЙФШУС У УПЛЕФПН, РТПГЕУУБ ДПМЦЕО ЙНЕФШ РТБЧП ОБ ЮФЕОЙС ЖБКМБ. иПФС ТБЪМЙЮОЩЕ ЛПНРШАФЕТЩ НПЗХФ УПЧНЕУФОП ЙУРПМШЪПЧБФШ ПДОХ ЖБКМПЧХА УЙУФЕНХ, ФПМШЛП РТПГЕУУЩ, ЪБРХЭЕООЩЕ ОБ ЬФПН ЛПНРШАФЕТЕ, НПЗХФ ЧЪБЙНПДЕКУФЧПЧБФШ ЙУРПМШЪХС УПЛЕФЩ МПЛБМШОПЗП РТПУФТБОУФЧБ ЙНЕО.

еДЙОУФЧЕООЩК ДПРХУФЙНЩК РТПФПЛПМ ДМС МПЛБМШОПЗП РТПУФТБОУФЧБ ЙНЕО — 0. рПУЛПМШЛХ ПО ОБИПДЙФУС Ч ЖБКМПЧПК УЙУФЕНЕ, МПЛБМШОЩК УПЛЕФ РТЕДУФБЧМЕО ЛБЛ ЖБКМ.

оБРТЙНЕТ, ПВТБФЙФЕ ЧОЙНБОЙЕ ОБ ОБЮБМШОХА s:

чЩЪПЧ unlink ХДБМСЕФ МПЛБМШОЩК УПЛЕФ, РТЙ ЪБЧЕТЫЕОЙЙ ТБВПФЩ У ОЙН.

рТЙНЕТ ЙУРПМШЪПЧБОЙС МПЛБМШОЩИ УПЛЕФПЧ

ч МЙУФЙОЗЕ 5.10 РТЕДУФБЧМЕОБ РТПЗТБННБ УЕТЧЕТБ, Ч ЛПФПТПК УПЪДБЕФУС МПЛБМШОЩК УПЛЕФ Й УМХЫБЕФ ЪБРТПУЩ ОБ УПЕДЙОЕОЙС У УЕТЧЕТПН. рТЙ РПМХЮЕОЙЙ ЪБРТПУБ ОБ УПЕДЙОЕОЙЕ, УЕТЧЕТ ЮЙФБЕФ ФЕЛУФПЧЩЕ УППВЭЕОЙС, РЕТЕДБЧБЕНЩЕ ЮЕТЕЪ УПЕДЙОЕОЙЕ Й РЕЮБФБЕФ ЙИ. еУМЙ ПДОП ЙЪ ЬФЙИ УППВЭЕОЙК — «ЧЩИПД», РТПЗТБННБ УЕТЧЕТБ ХДБМСЕФ УПЛЕФ Й ЪБЧЕТЫБЕФУС. рТПЗТБННБ socket-server РТЕДРПМБЗБЕФ, ЮФП РХФШ Л УПЛЕФХ РЕТЕДБЕФУС ЮЕТЕЪ РБТБНЕФТ ЛПНБОДОПК УФТПЛЙ.

лМЙЕОФ-РТПЗТБННБ, РТЕДУФБЧМЕООБС Ч МЙУФЙОЗЕ 5.11, УПЕДЙОСЕФУС У МПЛБМШОЩН УПЛЕФПН Й РПУЩМБЕФ УППВЭЕОЙС. рХФШ Л УПЛЕФХ Й УППВЭЕОЙС РЕТЕДБtФУС ЮЕТЕЪ ЛПНБОДОХА УФТПЛХ.

рЕТЕД РЕТЕДБЮЕК УППВЭЕОЙС, РПУЩМБЕФУС ТБЪНЕТ УППВЭЕОЙС Ч ВБКФБИ Ч ЛБЮЕУФЧЕ РЕТЕНЕООПК length. уЕТЧЕТ УПИТБОСЕФ ТБЪНЕТ УППВЭЕОЙС, ДМС ЧЩДЕМЕОЙС РБНСФЙ РПД УППВЭЕОЙЕ. юФПВЩ ЧЩРПМОЙФШ ЬФПФ РТЙНЕТ, ОЕПВИПДЙНП ЪБРХУФЙФШ УЕТЧЕТ-РТПЗТБННХ Ч ПДОПН ПЛОЕ, ПРТЕДЕМЙФШ РХФШ Л УПЛЕФХ.

ч ДТХЗПН ПЛОЕ ЪБРХУФЙФШ ЛМЙЕОФ-РТПЗТБННХ ОЕУЛПМШЛП ТБЪ, ПРЕТЕДЕМСС ПДЙО Й ФПФ ЦЕ РХФШ УПЛЕФБ Й РПУЩМБС ЛМЙЕОФХ УППВЭЕОЙЕ:

уЕТЧЕТ-РТПЗТБННБ РПМХЮБЕФ Й РЕЮБФБЕФ ЬФЙ УППВЭЕОЙС. дМС ЪБЛТЩФЙС УПЕДЙОЕОЙС, ЛМЙЕОФ РПУЩМБЕФ УППВЭЕОЙЕ «quit»:

Internet-Domain УПЛЕФЩ

CПЛЕФЩ UNIX-domain ЙУРПМШЪПЧБФШУС ФПМШЛП ДМС ЧЪБЙНПДЕКУФЧЙС ДЧХИ РТПГЕУУПЧ ФПМШЛП ОБ ПДОПН ЛПНРШАФЕТЕ. уПЛЕФЩ Internet, ЙУРПМШЪХАФУС ДМС УПЕДЙОЕОЙС ОЕУЛПМШЛЙИ РТПГЕУУПЧ ОБ ТБЪМЙЮОЩИ НБЫЙОБИ, РПДЛМАЮЕООЩИ Л УЕФЙ.

дМС УПЕДЙОЕОЙС РТПГЕУУПЧ ЮЕТЕЪ йОФЕТОЕФ УПЛЕФЩ ЙУРПМШЪХАФ РТПУФТБОУФЧП ЙНЕО йОФЕТОЕФ ХЛБЪЩЧБЕНПЕ У РПНПЭША PF_INET . вПМШЫЙОУФЧП РТПФПЛПМПЧ СЧМСАФУС TCP/IP . йОФЕТОЕФ РТПФПЛПМ ( IP ), РТПФПЛПМ ОЙЦОЕЗП ХТПЧОС, ПФРТБЧМСЕФ РБЛЕФЩ ЮЕТЕЪ йОФЕТОЕФ, ТБЪВЙЧБС ОБ НЕОШЫЙЕ РБЛЕФЩ, Ч УМХЮБЕ ОЕПВИПДЙНПУФЙ. пО ЗБТБОФЙТХЕФ ФПМШЛП ДПУФБЧЛХ «МХЮЫЕЗП ХУЙМЙС», ФБЛ ЮФП РБЛЕФЩ НПЗХФ ВЩФШ РПФЕТСОЩ ЙМЙ РЕТЕХРПТСДПЮЕОЩ ЧП ЧТЕНС ФТБОУРПТФЙТПЧЛЙ. лБЦДЩК ЛПНРШАФЕТ ЙНЕЕФ IP БДТЕУ. рТПФПЛПМ ХРТБЧМЕОЙС РЕТЕДБЮЕК ( TCP ), ЛПФПТЩК УМЕДХЕФ ЪБ IP РТПФПЛПМПН, ПВЕУРЕЮЙЧБЕФ ОБДЕЦОПЕ РПДЛМАЮЕОЙЕ. ьФП РПЪЧПМСЕФ ХУФБОПЧЙФШ НЕЦДХ ЛПНРШАФЕТБНЙ УПЕДЙОЕОЙЕ, ОБРПДПВЙЕ ФЕМЕЖПООПЗП Й ЗБТБОФЙТХЕФ ДПУФБЧЛХ ДБООЩИ Ч РБТЧЙМШОПН РПТСДЛЕ.

йОФЕТОЕФ БДТЕУ УПЛЕФБ УПУФПЙФ ЙЪ ДЧХИ ЮБУФЕК: ОПНЕТБ ЛПНРШАФЕТБ Й ОПНЕТБ РПТФБ. ьФБ ЙОЖПТНБГЙС ИТБОЙФУС Ч РЕТЕНЕООПК УФТХЛФХТЩ sockaddr_in . дМС ЙДЕОФЙЖЙЛБГЙЙ ФПЗП, ЮФП ЬФП БДТЕУ йОФЕТОЕФ РТПУФТБОУФЧБ ЙНЕО, ОЕПВИПДЙНП ХУФБОПЧЙФШ РПМЕ sin_family Ч AF_INET . ч РПМЕ Sin_addr ИТБОЙФУС йОФЕТОЕФ БДТЕУ ЛПНРШАФЕТБ, ЛБЛ 32-ТБЪТСДОПЕ ГЕМПЕ ЮЙУМП IP . лБЦДПНХ УПЛЕФХ ОБ ПДОПН ЛПНРШАФЕТЕ РТЙУЧБЙЧБЕФУС ОПНЕТ РПТФБ. рПУЛПМШЛХ ТБЪМЙЮОЩЕ НБЫЙОЩ УПИТБОСАФ НОПЗПВБКФПЧЩЕ ЪОБЮЕОЙС Ч ТБЪМЙЮОПН РПТСДЛЕ ВБКФБ, ЙУРПМШЪХАФ htons , ЮФПВЩ РТЕПВТБЪПЧБФШ ЮЙУМП РПТФБ Л УЕФЕЧПНХ РПТСДЛХ ВБКФПЧ.

лПНБОДБ gethostbyname РТЕПВТБЪПЧЩЧБЕФ ХДПВПЮЙФБЕНЩЕ ЙНЕОБ ИПУФБ, ЮЙУМБ УП УФБОДБТФОПК ФПЮЕЮОПК ОПФБГЙЕК (ФЙРБ 10.0.0.1) ЙМЙ DNS ЙНЕОБ (ФБЛЙЕ ЛБЛ www.codesourcery.com) Ч 32-ТБЪТСДОЩЕ IP БДТЕУБ. ч ЛБЮЕУФЧЕ ТЕЪХМШФБФБ ЧПЪЧТБЭБЕФУС ХЛБЪБФЕМШ ОБ УФТХЛФХТХ struct hostent ; Ч РПМЕ h_addr ИТБОЙФУС IP БДТЕУ ЗМБЧОПЗП ЛПНРШАФЕТБ.

мЙУФЙОЗ 5.12 ЙММАУФТЙТХЕФ ЙУРПМШЪПЧБОЙЕ Internet-domain УПЛЕФПЧ. рТПЗТБННБ РПМХЮБЕФ ДПНБЫОАА УФТБОЙГХ ПФ Web УЕТЧЕТБ, ЙНС ИПУФБ ЛПФПТПЗП ПРТЕДЕМЕОП Ч ЛПНБОДОПК УФТПЛЕ.

йНС ИПУФБ Web УЕТЧЕТБ ЪБДБЕФУС Ч ЛПНБОДОП УФТПЛЕ (ВЕЪ «http: //»). лПНБОДБ gethostbyname РТЕПВТБЪПЧЩЧБЕФ ЙНС ИПУФБ Ч ЮЙУМПЧПК IP БДТЕУ Й ЪБФЕН РПДЛМАЮБЕФ РПФПЛ (TCP) УПЛЕФБ Л РПТФХ 80 ОБ ЗМБЧОПН ЛПНРШАФЕТЕ. уЕТЧЕТЩ ЙУРПМШЪХАФ зЙРЕТФЕЛУФПЧЩК фТБОУРПТФОЩК рТПФПЛПМ ( HTTP ), РПЬФПНХ РЕТЕДБЕФУС ЛПНБОДБ HTTP GET , УЕТЧЕТ Ч ЛБЮЕУФЧЕ ПФЧЕФБ РЕТЕДБЕФ ФЕЛУФ ДПНБЫОЕК УФТБОЙГЩ.

дМС ПФПВТБЦЕОЙС УФТБОЙГЩ www.codesourcery.com, ОЕПВИПДЙНП ЪБДБФШ УМЕДХАЭХЕ ЛПНБОДХ

рБТЩ УПЛЕФПЧ

лБЛ ХРПНЙОБМПУШ ТБОЕЕ, ЖХОЛГЙС pipe , УПЪДБЕФ ДЧБ ДЕУЛТЙРФПТБ ЖБКМПЧ ДМС ОБЮБМБ Й ЛПОГБ ЛБОБМБ. лБОБМЩ ПЗТБОЙЮЕОЩ, РПФПНХ ЮФП ДЕУЛТЙРФПТЩ ЖБКМПЧ ЙУРПМШЪХАФУС ФПМШЛП УЧСЪБООЩНЙ РТПГЕУУБНЙ Й РПФПНХ ЮФП ЧЪБЙНПДЕКУФЧЙЕ ПДОПОБРТБЧМЕОП. жХОЛГЙС socketpair УПЪДБЕФ ДЧБ ДЕУЛТЙРФПТБ ЖБКМПЧ ДМС ДЧХИ УПЛЕФПЧ, РПДЛМАЮЕООЩИ ОБ ПДОПН ЛПНРШАФЕТЕ. ьФЙ ДЕУЛТЙРФПТЩ ЖБКМПЧ ТБЪТЕЫБАФ ДЧХИУФПТПООЕЕ ЧЪБЙНПДЕКУФЧЙЕ ДЧХИ УЧСЪБООЩИ РТПГЕУУПЧ. рЕТЧЩЕ ФТЙ РБТБНЕФТБ ЛПНБОДЩ — ЙДЕОФЙЮОЩ РБТБНЕФТБН ЛПНБОДЩ socket : ПОЙ ПРТЕДЕМСАФ ДПНЕО, УФЙМШ РПДЛМАЮЕОЙС Й РТПФПЛПМ. рПУМЕДОЙК РБТБНЕФТ — НБУУЙЧ У ДЧХНС ГЕМЩНЙ ЮЙУМБНЙ, Ч ЛПФПТПН ИТБОСФУС ИБТБЛФЕТЙУФЙЛЙ ЖБКМПЧ ЬФЙИ ДЧХИ УПЛЕФПЧ. рТЙ ЙУРПМШЪПЧБОЙЙ ЛПНБОДЩ socketpair , ОЕПВИПДЙНП ПРТЕДЕМЙФШ PF_LOCAL ЛБЛ РТПУФТБОУФЧП ЙНЕО.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL