Что такое дескриптор сокета
Перейти к содержимому

Что такое дескриптор сокета

  • автор:

12. Что такое дескриптор сокета?

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

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

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

Рис. 1

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

Интерфейс сокетов не определяет никаких способов управления дескриптором сокета. Сам UNIX обращается с дескрипторами сокетов точно так же, как с дескрипторами файлов. Другие приложения могут обращаться с дескрипторами так, как это им заблагорассудится. Другими словами, то, что происходит с данными, на которые указывает дескриптор, зависит от конкретной реализации системы, с которой вы работаете. Вам, как прикладному программисту, не обязательно знать подробности, касающиеся таблиц дескрипторов, структуры данных в них и отведения памяти. Мы рассматриваем все это, только чтобы показать, каким образом сокету присваивается сетевой адрес. Функция socket образует структуру данных сокета, не заполняя при этом поля адресов. Чтобы связать сокет с определенным сетевым адресом, необходимо вызвать другие функции, входящие в состав API, так, как это будет показано в следующих разделах.

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

Сетевой уровень IP идентифицирует сетевые компьютеры при помощи сетевого адреса. Это значит, что каждый компьютер, подключенный к Интернет, должен иметь уникальный сетевой адрес. Ранее объяснялось, как транспортный уровень использует адреса портов для обозначения определенных приложений (процессов) в сетевом компьютере. Каждый сетевой процесс, таким образом, использует номер порта сетевого компьютера в качестве собственного адреса. Наконец, вы знаете, что программы Интернет должны использовать семейство протоколов TCP/IP для передачи своих данных по сети. Таким образом, соединение между двумя сетевыми программами несет в себе следующую информацию:

— местный (локальный) порт протокола, обозначающий программу или процесс, посылающий сообщения или датаграммы;

— адрес локального компьютера, обозначающий сетевой компьютер, принимающий пакеты данных;

— удаленный порт протокола, обозначающий программу или процесс-получатель данных;

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

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

5. Отличие дескриптора сокета от дескриптора файла

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

Рассмотрим потребности сетевой программы TCP/IP, передающей информацию датаграммами по не ориентированному на соединение протоколу. Программа указывает адрес назначения датаграмм, но не устанавливает предварительного соединения с компьютером-получателем данных. Вместо этого программа передает датаграммы по адресу назначения. Сетевое программное обеспечение (уровень IP) обслуживает процесс доставки. Чтобы интегрировать TCP/IP в среду UNIX, разработчики сокетов должны были добавить к существующей системе ввода-вывода новые возможности. API сети TCP/IP был необходим способ получать дескриптор ввода-вывода, не устанавливая предварительно соединения с удаленным компьютером. Вместо того чтобы модифицировать существующую систему ввода-вывода UNIX, разработчики сокетов создали новую функцию, которая и получила название «сокет» (socket). В следующем разделе вы узнаете, как функция socket позволяет программе получить дескриптор сокета, не указывая адрес получателя сетевых данных.

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

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

socket_handle = socket (protocol_family, socket_type, protocol);

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

Дескриптор сокета

При необходимости дескриптор сокета может быть дескриптором файла в Windows Sockets 2. Дескриптор сокета от поставщика Winsock можно использовать с другими функциями, не предназначенными для Winsock, такими как ReadFile, WriteFile,ReadFileEx и WriteFileEx.

Элемент XP1_IFS_HANDLES в структуре сведений о протоколе для поставщика определяет, является ли дескриптор сокета от поставщика дескриптором устанавливаемой файловой системы (IFS). Дескрипторы сокета, являющиеся дескрипторами IFS, можно использовать без снижения производительности с другими функциями, не имеющими winsock (например, ReadFile и WriteFile). Любые дескрипторы сокета, отличные от IFS, при использовании с функциями, не связанными с Winsock (например, ReadFile и WriteFile), приводят к взаимодействию между поставщиком и файловой системой, в которых возникают дополнительные затраты на обработку, что может привести к значительному снижение производительности. При использовании дескрипторов сокетов с функциями, не использующими Winsock, коды ошибок, распространяемые из базовой файловой системы, не всегда сопоставляются с кодами ошибок Winsock. Следовательно, рекомендуется использовать дескриптор сокета только с функциями Winsock.

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

Многоуровневые поставщики служб являются устаревшими. Начиная с Windows 8 и Windows Server 2012, используйте платформу фильтрации Windows.

В windows Sockets 2 расширены некоторые функции, которые передают данные между сокетами с помощью дескрипторов. Функции предоставляют преимущества, характерные для сокетов для передачи данных, и включают WSARecv, WSASend и WSADuplicateSocket.

Сокеты и дескрипторы

Добрый день! Насколько я понимаю, есть 3 способа писать-читать в сокеты:

1. Использовать интерфейс сокетов (recv, send). Используется т.н. дескриптор сокета, возвращаемый функциями accept() у сервера и непосредственно socket() у клиента. Правда, socket() у сервера тоже возвращает дескриптор, но после accept() мы имеем дескриптор, «направленный» на конкретного клиента. А поскольку у клиента по одному сокету всегда «висит» один сервер, то там достаточно того, что возвращает socket(). При этом что будет, если сервер запишет что-нибудь через send() и дескриптор, возвращенный ему socket() – неясно. Кто из клиентов это получит? 2. Как известно, дескриптор сокета ничем (с определенной точки зрения) не отличается от дескриптора файла, они указывают на элементы в одной таблице и т.д. Можно (по крайней мере клиенту) закрыть перед подключением 1-й или 2-й дескрипторы через close(), и потом сокет получит этот номер (первый не занятый в таблице дескрипторов), при этом он встанет на место stdout или stderr. Можно будет работать с ним как с stdout, например. Говорили, что в данном случае всю работу на себя возьмет демон inetd. Правда, мне не ясно, можно ли поставить сокет одновременно на место stdin и stdout (видимо, сдублировав дескриптор, например, через fcntl), и каков режим его открытия применительно к обычным режимам открытия файлов (я подозреваю, что у каждого сокета это – одновременно на чтение и запись). И неясно, может ли сервер так делать. 3. Можно, наверное, писать в сокет как в файл. Правда, все функции (fwrite(), fputs() и др.) требуют параметр типа FILE*. Как преобразовать int (дескриптор) в FILE*, ума не приложу.

Все 3 подхода наверняка имеют свои плюсы и минусы. Но я никак не пойму, какие. Прошу совета. Наверное, какой-то более переносим, а какой-то менее? И вы, лично вы, если бы вам дали писать простенький клиент SMTP, скажем, вы бы какой из трех подходов выбрали и почему? А какой бы не выбрали и почему? А если клиент/сервер FTP? (ну и пара вопросов была задана в самой формулировке пунктов 1, 2, 3).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *