sem15 - Сокеты. Мультиплексирование ввода-вывода. (Мини-учебник с ejudge = Чернокнижка)
Описание файла
Файл "sem15 - Сокеты. Мультиплексирование ввода-вывода." внутри архива находится в папке "Мини-учебник с ejudge = Чернокнижка". PDF-файл из архива "Мини-учебник с ejudge = Чернокнижка", который расположен в категории "". Всё это находится в предмете "практика расчётов на пэвм" из 3 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст из PDF
Содержание1 Сокеты1.1 Адресация компьютеров . . . . . . . . . .1.2 Сетевое представление чисел . . . . . . . .1.3 Связь с установлением соединения . . . . .1.3.1 Создание сокета . . . . . . . . . . .1.3.2 Работа клиента . . . . . . . . . . .1.3.3 Работа сервера . . .
. . . . . . . .1.3.4 Обмен данными . . . . . . . . . . .1.3.5 Установка режимов работы сокета .1.4 Пример клиента . . . . . . . . . . . . . . .1.5 Пример сервера . . . . . . . . . . . . . . .........................................................................................................................................................................................................2 Мультиплексирование ввода/вывода11123345667810СокетыВ данном разделе мы рассмотрим ещё один механизм межпроцессного взаимодействия— сокеты. Сокеты — это универсальный интерфейс межпроцессного взаимодействия, допускающий взаимодействие процессов, работающих как на одном компьютере, так и на разных компьютерах, объединённых в сеть.
Изначально интерфейс сокетов был реализован для4.2BSD, затем был перенесён на все другие Unix-подобные операционные системы. Значительно позднее похожий интерфейс был реализован для Windows 3.1. Несмотря на то, чтофункции работы с сокетами называются в Windows точно также, работа с ними в деталяхотличается от работы с сокетами в Unix, поэтому говорить о совместимости не приходится.Мы рассмотрим работу с сокетами только в случае сети компьютеров и с установлениемвиртуального соединения.
Обмен данными в этом случае ведётся по протоколу TCP.1.1 Адресация компьютеровКаждый компьютер в сети IP должен иметь уникальный номер (адрес). В настоящее время (протокол IPv4) адрес имеет размер 32 бита (4 байта) 1 . Традиционно IP-адреса записываются в точечной нотации: 4 десятичных числа, каждое для соответствующего байта адреса,начиная от старшего байта к младшему, разделённые точкой, например 192.168.10.1.Чтобы преобразовать адрес в точечной нотации в одно 32-битное слово можно использовать функцию gethostbyaddr.#include <netdb.h>#include <sys/socket.h>struct hostent *gethostbyaddr(char const *addr, int len, int type);Здесь параметр addr — это адрес, len — длина строки адреса, type — тип адреса,этот параметр должен быть установлен в AF_INET. В случае неудачи возвращается NULL, ав случае успеха возвращается указатель на заполненную структуру hostent.1Вновой версии протокола IP — IPv6 — адрес имеет размер 128 бит. Впрочем, переход на новый протоколтолько начинается.1struct hostent {char*h_name;char**h_aliases;inth_addrtype;inth_length;char**h_addr_list;};/*/*/*/*/*официальное имя */список алиасов имени */тип адреса (AF_INET) */длина адреса (4) */список адресов */Указатели на адреса во внутреннем представлении находятся в массиве h_addr_list.Последний элемент массива содержит NULL.
Чтобы сделать описание структуры максимально общим, разработчики сделали указатель на внутреннее представление адреса указателем типа char*, что здесь по смыслу то же самое, что void* 2. Чтобы использоватьадреса нужно либо приводить тип указателя к типу unsigned long *, либо использоватьфункции типа memcpy.Поскольку запись адресов в десятичной нотации немнемонична, была разработана доменная система имён. Имя компьютера в доменной системе имён записывается как последовательность из нескольких слов, разделённых точкой, например www.cs.msu.su. В локальных сетях могут использоваться имена, состоящие только из одного слова, напримерelwing. Чтобы преобразовать доменное имя компьютера в его адрес во внутреннем представлении можно использовать функцию gethostbyname.#include <netdb.h>struct hostent *gethostbyname(char const *name);Если вызов закончился неудачно, функция возвращает NULL, а в случае удачи возвращается указатель на структуру hostent, описанную выше.
В Unix gethostbyname корректнообрабатывает адреса компьютеров в точечной нотации, в отличие от Windows.IP-адрес 127.0.0.1 на любом компьютере обозначает этот же компьютер. Этому адресу соответствует имя localhost.Иногда требуется по адресу во внутреннем представлении получить адрес в точечной нотации. Для этого используется функция inet_ntoa.#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>char *inet_ntoa(struct in_addr in);По адресу во внутреннем представлении, передаваемом в параметре in, эта функция возвращает указатель на строку, содержащую запись адреса в точечной нотации. Строка размещается в статической области памяти, поэтому содержимое строки переписывается прикаждом вызове функции. Структура struct in_addr определена следующим образом.struct in_addr {unsigned long int s_addr;};Поле s_addr содержит адрес компьютера во внутреннем представлении (32-битное целое число в сетевом представлении).Кроме адреса компьютера для установления связи необходимо знать номер порта.
Это— небольшое (16 бит) неотрицательное целое число. Именно по номеру порта различаются2 Когдаразрабатывался интерфейс сокетов, в языке Си ещё не было ключевого слова void.2разные сетевые сервисы, работающие на одном компьютере. Например, порт с номером 80обычно используется web-сервером, а порт с номером 25 — почтовым сервером. Порты сномерами, меньшими 1025 зарезервированы для использования привилегированными процессами.
Все остальные порты доступны для использования всеми процессами. Если процесс не выполнил операцию привязки сокета к определённому номеру порта, номер портаназначается автоматически. К одному и тому же порту могут подключаться несколько клиентов, поэтому соединение полностью идентифицируется 4 числами: двумя адресами компьютеров и двумя номерами портов.1.2 Сетевое представление чиселВ сети могут работать компьютеры различных аппаратных платформ под управлениемразличных операционных систем.
Даже целые числа хранятся в памяти по-разному у разных типов процессоров. Например, у процессоров i386 и выше целые числа хранятся в памяти от младшего байта к старшему (Little Endian). У других процессоров (например, sparc)целые числа хранятся в памяти от старшего байта к младшему (Big Endian).
Поэтому необходимо единое согласованное представление целых чисел при пересылке пакетов по сети 3 . Вкачестве такого представления выбрано представление от старшего байта к младшему. Дляперевода целых чисел из сетевого представления в локальное и наоборот определены следующие функции.#include <netinet/in.h>unsignedunsignedunsignedunsignedlong int htonl(unsigned long int hostlong);short int htons(unsigned short int hostshort);long int ntohl(unsigned long int netlong);short int ntohs(unsigned short int netshort);Функция htonl переводит длинное целое (32 бита) из локального представления в сетевое представление. Функция ntohl переводит длинное целое (32 бита) из сетевого представления в локальное. Функция htons переводит короткое целое (16 бит) из локальногопредставления в сетевое, а функция ntohs — наоборот.
Когда по сети передаются целыечисла в двоичном представлении, они должны быть преобразованы в сетевое представление.Заметьте, что не существует стандартных способов передачи по сети вещественных чиселв бинарном формате. Предпочтительнее их преобразовывать в символьное представление.1.3 Связь с установлением соединенияРассмотрим взаимодействие двух процессов, когда они связываются с установлениемвиртуального соединения.
В этом случае работа двух сторон не симметрична. Один процесс должен выступить в роли «сервера», другой — в роли «клиента». Такое разделениеможет не иметь ничего общего с архитектурой «клиент-сервер», но чаще всего роли сторон вархитектуре «клиент-сервер» естественно отображаются на роли сторон при установлениисоединения.Сервер должен создать сокет, привязать его к определённому порту и/или адресу, переключить сокет в режим ожидания соединения, затем ожидать подключения от клиента. Клиент должен создать сокет, после этого он может привязать его к определённому порту и/или3И вообще, необходимо согласованное представление любых пересылаемых данных. Для этого предназначены такие языки, как ASN.1, IDL и пр.3адресу, затем клиент должен подключиться к серверу.
После установления соединения обестороны могут обмениваться информацией друг с другом.1.3.1 Создание сокетаРассмотрим эти шаги подробнее. Чтобы создать сокет используется системный вызовsocket.#include <sys/types.h>#include <sys/socket.h>int socket(int domain, int type, int protocol);Параметр domain задаёт коммуникационный домен. Например, PF_UNIX, PF_LOCAL— это локальное соединение, которое доступно только для процессов, работающих на одном компьютере, но его мы здесь рассматривать не будем.