Самодел 2 (1114717), страница 17

Файл №1114717 Самодел 2 (Старые версии Машбука или нечто подобное) 17 страницаСамодел 2 (1114717) страница 172019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 17)

Возвращает:

В случае успешного связывания bind возвращает 0, в случае ошибки – -1.

Сокеты с предварительным установлением соединения. Запрос на соединение

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

Запрос на соединение

#include <sys/types.h>

#include <sys/socket.h>

int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);

sockfd – дескриптор сокета

serv_addr – указатель на структуру, содержащую адрес сокета, с которым производится соединение, в формате, который мы обсуждали выше

addrlen – реальная длина структуры

Возвращает:

В случае успешного связывания функция возвращает 0, в случае ошибки – -1. Код ошибки заносится в errno.

Заметим, что в рамках модели «клиент-сервер» клиенту, вообще говоря, не важно, какой адрес будет назначен сокету, т.к. никакой процесс не будет пытаться непосредственно установить соединение с сокетом клиента. Поэтому клиент может не вызывать предварительно функцию bind, в этом случае при вызове connect система автоматически выберет приемлемые значения для локального адреса клиента. Однако сказанное справедливо только для взаимодействия в рамках домена AF_INET, в домене AF_UNIX клиентское приложение само должно позаботиться о связывании сокета.

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

Прослушивание сокета

Этот вызов используется процессом-сервером для того, чтобы сообщить системе о том, что он готов к обработке запросов на соединение, поступающих на данный сокет. До тех пор, пока процесс – владелец сокета не вызовет listen, все запросы на соединение с данным сокетом будут возвращать ошибку.

#include <sys/types.h>

#include <sys/socket.h>

int listen (int sockfd, int backlog);

sockfd – дескриптор сокета

backlog – максимальный размер очереди запросов на соединение. ОС буферизует приходящие запросы на соединение, выстраивая их в очередь до тех пор, пока процесс не сможет их обработать. В случае если очередь запросов на соединение переполняется, поведение ОС зависит от того, какой протокол используется для соединения. Если конкретный протокол соединения не поддерживает возможность перепосылки (retransmission) данных, то соответствующий вызов connect вернет ошибку ECONNREFUSED. Если же перепосылка поддерживается (как, например, при использовании TCP), ОС просто выбрасывает пакет, содержащий запрос на соединение, как если бы она его не получала вовсе. При этом пакет будет присылаться повторно до тех пор, пока очередь запросов не уменьшится и попытка соединения не увенчается успехом, либо пока не произойдет тайм-аут, определенный для протокола. В последнем случае вызов connect завершится с ошибкой ETIMEDOUT. Это позволит клиенту отличить, был ли процесс-сервер слишком занят, либо он не функционировал. В большинстве систем максимальный допустимый размер очереди равен 5.

Возвращает:

В случае успешного связывания функция возвращает 0, в случае ошибки – -1. Код ошибки заносится в errno.

Подтверждение соединения

Этот вызов применяется сервером для удовлетворения поступившего клиентского запроса на соединение с сокетом, который сервер к тому моменту уже прослушивает (т.е. предварительно была вызвана функция listen). Accept извлекает первый запрос из очереди и устанавливает с ним соединение. Если к моменту вызова accept никаких запросов на соединение с данным сокетом еще не поступало, процесс, вызвавший accept, блокируется до поступления запросов. Когда запрос поступает и соединение устанавливается, accept возвращает дескриптор нового сокета, соединенного с сокетом клиентского процесса. Через этот новый сокет и осуществляется обмен данными, в то время как старый сокет продолжает обрабатывать другие поступающие запросы на соединение (напомним, что именно первоначально созданный сокет связан с адресом, известным клиентам, поэтому все клиенты могут слать запросы только на соединение с этим сокетом). Это позволяет процессу-серверу поддерживать несколько соединений одновременно. Обычно это реализуется путем порождения для каждого установленного соединения отдельного процесса-потомка, который занимается собственно обменом данными только с этим конкретным клиентом, в то время как процесс-родитель продолжает прослушивать первоначальный сокет и порождать новые соединения.

#include <sys/types.h>

#include <sys/socket.h>

int accept (int sockfd, struct sockaddr *addr, int *addrlen);

sockfd – дескриптор сокета

addr – указатель на структуру, в которой возвращается адрес клиентского сокета, с которым установлено соединение (если адрес клиента не интересует, передается NULL).

addrlen – возвращается реальная длина этой структуры. максимальный размер очереди запросов на соединение.

Благодаря второму и третьему аргументам сервер всегда знает, куда ему в случае надобности следует послать ответное сообщение. Если адрес клиента нас не интересует, в качестве второго аргумента можно передать NULL.

Возвращает:

Возвращает дескриптор нового сокета, соединенного с сокетом клиентского процесса.

Приём и передача данных.

#include <sys/types.h>

#include <sys/socket.h>

int send(int sockfd, const void *msg, int len, unsigned int flags);

sockfd - дескриптор сокета, через который передаются данные

msg – сообщение

len – длина сообщения

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

Возвращает:

Возвращает количество переданных байт в случае успеха и -1 в случае неудачи. Код ошибки при этом устанавливается в errno.

int recv(int sockfd, void *buf, int len, unsigned int flags);

sockfd - дескриптор сокета, через который передаются данные

buf – указатель на буфер для приема данных

len – первоначальная длина буфера.

Возвращает:

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

Общий аргумент flags:

flags - может содержать комбинацию специальных опций.

MSG_OOB - флаг сообщает ОС, что процесс хочет осуществить прием/передачу экстренных сообщений

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

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

Другая пара функций, которые могут использоваться при работе с сокетами с предварительно установленным соединением – это обычные read() и write(), в качестве дескриптора которым передается дескриптор сокета.

И, наконец, пара функций, которая может быть использована как с сокетами с установлением соединения, так и с сокетами без установления соединения:

#include <sys/types.h>

#include <sys/socket.h>

int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to,

int tolen);

Первые 4 аргумента – такие же, как у рассмотренных раньше.

to - указатель на структуру, содержащую адрес получателя

tolen – размер структуры to.

int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from,

int *fromlen);

Первые 4 аргумента – такие же, как у рассмотренных раньше.

from- указатель на структуру с адресом отправителя

fromlen – размер структуры from.

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

Если процесс закончил прием либо передачу данных, ему следует закрыть соединение. Это можно сделать с помощью функции shutdown.

#include <sys/types.h>

#include <sys/socket.h>

int shutdown (int sockfd, int mode);

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

mode – режим закрытия соединения (целое число)

= 0, сокет закрывается для чтения, при этом все дальнейшие попытки чтения будут возвращать end-of-file.

= 1, сокет закрывается для записи, и дальнейшие попытки передать данные вернут ошибку (-1).

= 2, сокет закрывается и для чтения, и для записи

Возвращает:

В случае успеха функция возвращает 0, в случае неудачи -1

Аналогично файловому дескриптору, дескриптор сокета освобождается системным вызовом close( ).

В принципе, для закрытия сокета можно было бы воспользоваться просто функцией close, но тут есть одно отличие. Если используемый для соединения протокол гарантирует доставку данных (тип сокета – виртуальный канал), то вызов close будет блокирован до тех пор, пока система будет пытаться доставить все данные, находящиеся «в пути», в то время как вызов shutdown извещает систему о том, что эти данные уже не нужны и можно не предпринимать попыток их доставить.

С хема работы с сокетами с установлением соединения

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


Схема работы с сокетами без установления соединения

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

Пример. Работа с локальными сокетами

Рассмотрим небольшой пример, иллюстрирующий работу с сокетами в рамках локального домена (AF_UNIX). Ниже приведена небольшая программа, которая в зависимости от параметра командной строки исполняет роль клиента или сервера. Клиент и сервер устанавливают соединение с использованием датаграммных сокетов. Клиент читает строку со стандартного ввода и пересылает серверу; сервер посылает ответ в зависимости от того, какова была строка. При введении строки «quit» и клиент, и сервер завершаются.

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/un.h>

#include <stdio.h>

#include <string.h>

#define SADDRESS "mysocket"

#define CADDRESS "clientsocket"

#define BUFLEN 40

int main(int argc, char **argv)

{

struct sockaddr_un party_addr, own_addr;

int sockfd;

int is_server;

char buf[BUFLEN];

int party_len;

int quitting;

if (argc != 2) {

printf("Usage: %s client|server.\n", argv[0]);

return 0;

}

quitting = 1;

is_server = !strcmp(argv[1],"server");

memset(&own_addr, 0, sizeof(own_addr));

own_addr.sun_family = AF_UNIX;

strcpy(own_addr.sun_path,

is_server?SADDRESS:CADDRESS);

if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0))<0){

printf("can't create socket\n");

return 0;

}

unlink(own_addr.sun_path); /* связываем сокет */

if (bind(sockfd, (struct sockaddr *) &own_addr,

sizeof(own_addr.sun_family)+

strlen(own_addr.sun_path)) < 0)

{

printf("can't bind socket!");

return 0;

}

if (!is_server) { /* это – клиент */

memset(&party_addr, 0, sizeof(party_addr));

party_addr.sun_family = AF_UNIX;

strcpy(party_addr.sun_path, SADDRESS);

printf("type the string: ");

while (gets(buf)) {/* не пора ли выходить? */

quitting = (!strcmp(buf, "quit"));

/* считали строку и передаем ее серверу */

if (sendto(sockfd, buf, strlen(buf) + 1, 0,

(struct sockaddr *) &party_addr,

sizeof(party_addr.sun_family) +

strlen(SADDRESS)) != strlen(buf) + 1)

{

Характеристики

Тип файла
Документ
Размер
4,18 Mb
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6310
Авторов
на СтудИзбе
312
Средний доход
с одного платного файла
Обучение Подробнее