КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Сокеты дейтаграммного типа.Если bind не организован, то данные мб только отправляться. Int sendto(int s, const void*buf, int len, int flags, const struct sockaddr*to, socklen_t*tolen); Int recvfrom(int s, const void*buf, int len, int flags, const struct sockaddr*from, socklen_t*fromlen); Параметр s задает дескриптор сокетов, buf указывает на буфер, содержащий данные для передачи, либо для размещения принятых, len размер, flags используется для задания дополнительных опций (для норм работы поставить 0), в вызове sendto параметр to указывает на структуру, содержащую адрес сокета, на который необходимо отправить данные, адрес получателя сообщения (sockaddr_in для AF_INET, sockaddr_un для AF_UNIX) параметр to len равен размеру этой структуры. Параметр from указывает на структуру в которой нужно записать адрес отправителя, fromlen представляет собой указатель на переменную типа socklen_t. Причем передающая система вызовом кусмакщь в неее нужно занести размер адресной структуры. После вызова переменной содержащей количество байт, который вызывается в эту структуру в итоге записан.
45. Потоковые сокеты. Клиент – серверная модель. Перед началом взаимодействия устанавливают соединение. Здесь мы обязательно имеем клиента и сервера. Сервер – прога, ожидающая запроса и производящая действия исключительно в ответ. Клиент – прога, обращающаяся с запросами к серверу. Организация сервера: чтобы начать ожидание запросов на соединение сервер задает сокет соотв. типа, связывает его с адресом и переводит в «слушающее» состояние (L на схеме). На таком сокете мб осуществлена только 1 операция «принятия» соединения. При установлении соединения ядро создает еще 1 сокет, который используется для передачи данных по установленному соед-ю: sd - связан с сокетом ФД; int listen (int sd, int qlen) qlen - задает размер очереди не принятой запросом на соединение (5-6) Допустим перевели сокет в слушающий режим, а несколько клиентов уже отправили запросы на соед-е. В силу опред. Причин эти запросы не принимаются, возможности системы ограничены. Первые qlen запросов будут ожидать принятия соединения, остальные будут отклонены. int accept (int sd, struct sockaddr *addr, socklen_t *addrlen) sd - ФД слушающего сокета; addr – структура в которую записывают адрес сокета, с которым установлено соединение. addrlen – указатель на переменную типа socklen_t. В эту переменную перед вызовом accept следует занести размер адресной структуры. После возврата accept эта переменная будет содержать количетсво байт, записанных в эту структуру. Возвращает accept ФД нового сокета для нового соединения. Если на момент выполнения accept запросов на соединение еще не поступало, тогда вызов блокирует вызвавший процесс и ожидает запроса на соединение.
Организация клиента: связывать сокет с адресом не обязательно, если этого не сделать система выберет адрес автоматически. Запрос на соединение формируется вызовом: int connect (int sd, struct sockaddr *addr, int *addrlen) sd - связан с сокетом ФД; addr – указывает на структуру, содержащую адрес сервера, т.е. адрес «слушающего» сокета. addrlen – дб равен размеру этой структуры.
Обмен данными: после успешнгого установления соединения для передачи данных можно использовать read/write. Существуют спец системные вызовы revc(), send(), Отличаются от read/write только наличием флагов. Завершить работу с сокетом: int shutdown (int sd, int how) how – что именно надо прекратить (0 – закрыть на чтение, 1 - …на запись, Закрыть сокет: int close (int sd) 2 - …оба направления) Shutdown только прекращает обмен данными в сокете, а close уберет сам ФД. Если дальний конец соединения закрыт очередной вызов read или recv вернет 0 => конец файла.
Организация функции преобразования адресов: Порядок байт в представлении целых чисел может варьироваться в зависимости от архитектуры. Архитектура в которой старший байт числа имеет наименьший адрес (прямой порядок) big-endian. Другой вариант: наименьший адрес имеет младший байт (обратный порядок) little-endian. Чтобы сделать возможнымвзаимодейтсвие по сети между машинами с разными архитектурами принято соглашение, что передача целочисленной информации по сети всегда идет в прямом порядке байт. Чтобы обеспечить переносимость программ на уровне исход кода в UNIX есть стандартные функции для преобразования целых чисел из формата данной машины в сетевой формат. На машине порядок байт в архитектуре которой совпадает с сетевым эти функции вернут аргумент, иначе они произведут преобразование:
unsigned long int htonl (unsigned long int hostlong); n (network) – сетевой порядок байт unsigned short int htons (unsigned short int hostshort); h (host) – порядой байт данной машины unsigned long int ntohl (unsigned long int netlong); s – короткие целые, l – длинные целые. unsigned short int ntohs (unsigned short int netshort); При работе с сервером можно отметить след. ситуацию: после завершения программы-сервера ее некоторое время можно запустить с тем же номером порта. Это происходит при некорректном завершении проги-сервера, либо если завершение происходит при активных клиентских соединениях. Ядро ОС продолжает читать адрес «занято». Система сокетов позволяет изменить поведение ядра в отношении адресов зависших подобным образом («залипших»). Для этого перед вызовом bind необходимо выставить на будущем «слушающем» сокете опцию: SO_REUSEADDR. Это делается с помощью сист вызова: int setsockopt (int sd, int level, int optname, const void *optval, int optlen) sd – дескриптор сокета. level – уровень стека протоколов. В данной опции уровень SOL_SOCKET. optname – номер или числовой идентификатор (SO_REUSEADDR). Т.е. информация связанная с этой опцией может иметь разную сложность. Вызов принимает безтиповый указатель назначения опции и длины опции. optval = 1; optlen = sizeof(int); int opt = 1 Пример: setsockopt (ls,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(int)); В отличие от неименованных каналов сокеты представляют собой двунапраленный канал связи, что часто более удобно. В UNIX предусмотрен вызов: int socketpair (int af, int type, int protocol, int sv[2]); af, type, protocol – задают семейство адресации, тип и протокол для создаваемого сокета соотв-но AF_UNIX, SOCK_STREAM, 0. sv – должен указывать на массив из 2х элементов целого типа в котор вызов занесет ФД 2х созданных структур. Сокеты будут уже связаны друг с другом при чем оба конца открыты на чтение и запись.
|