Часть полного текста документа:Программа-клиент Работа с WinSocket Socket (гнездо, разъем) - абстрактное программное понятие, используемое для обозначения в прикладной программе конечной точки канала связи с коммуникационной средой, образованной вычислительной сетью. При использовании протоколов TCP/IP можно говорить, что socket является средством подключения прикладной программы к порту (см. выше) локального узла сети. Socket-интерфейс представляет собой просто набор системных вызовов и/или библиотечных функций языка программирования СИ, разделенных на четыре группы: 1. Локального управления 2. Установления связи 3. Обмена данными (ввода/вывода) 4. Закрытия связи 5. Пример использования WinSocket Ниже рассматривается подмножество функций socket-интерфейса, достаточное для написания сетевых приложений, реализующих модель "клиент-сервер" в режиме с установлением соединения. 1. Функции локального управления Функции локального управления используются, главным образом, для выполнения подготовительных действий, необходимых для организации взаимодействия двух программ-партнеров. Функции носят такое название, поскольку их выполнение носит локальный для программы характер. 1.1 Создание socket'а Создание socket'а осуществляется следующим системным вызовом #include int socket (domain, type, protocol) int domain; int type; int protocol; Аргумент domain задает используемый для взаимодействия набор протоколов (вид коммуникационной области), для стека протоколов TCP/IP он должен иметь символьное значение AF_INET (определено в sys/socket.h). Аргумент type задает режим взаимодействия: SOCK_STREAM - с установлением соединения; SOCK_DGRAM - без установления соединения. Аргумент protocolзадает конкретный протокол транспортного уровня (из нескольких возможных в стеке протоколов). Если этот аргумент задан равным 0, то будет использован протокол "по умолчанию" (TCP для SOCK_STREAM и UDP для SOCK_DGRAM при использовании комплекта протоколов TCP/IP). При удачном завершении своей работы данная функция возвращает дескриптор socket'а - целое неотрицательное число, однозначно его идентифицирующее. Дескриптор socket'а аналогичен дескриптору файла ОС UNIX. При обнаружении ошибки в ходе своей работы функция возвращает число "-1". 1.2. Связывание socket'а Для подключения socket'а к коммуникационной среде, образованной вычислительной сетью, необходимо выполнить системный вызов bind, определяющий в принятом для сети формате локальный адрес канала связи со средой. В сетях TCP/IP socket связывается с локальным портом. Системный вызов bind имеет следующий синтаксис: #include #include #include int bind (s, addr, addrlen) int s; struct sockaddr *addr; int addrlen; Аргумент s задает дескриптор связываемого socket'а. Аргумент addr в общем случае должен указывать на структуру данных, содержащую локальный адрес, приписываемый socket'у. Для сетей TCP/IP такой структурой является sockaddr_in. Аргумент addrlen задает размер (в байтах) структуры данных, указываемой аргументом addr. Структура sockaddr_in используется несколькими системными вызовами и функциями socket-интерфейса и определена в include-файле in.h следующим образом: struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; Поле sin_family определяет используемый формат адреса (набор протоколов), в нашем случае (для TCP/IP) оно должно иметь значение AF_INET. Поле sin_addr содержит адрес (номер) узла сети. Поле sin_port содержит номер порта на узле сети. Поле sin_zero не используется. Определение структуры in_addr (из того же include-файла) таково: struct in_addr { union { u_long S_addr; /* другие (не интересующие нас) члены объединения */ } S_un; #define s_addr S_un.S_addr }; Структура sockaddr_in должна быть полностью заполнена перед выдачей системного вызова bind. ............ |