3. Механизм сокетов 3.1. Общие концепции 3.2. Интерфейсные функции для работы с сокетом 3.2.1. Создание сокета 3.2.2. Связывание и установление соединения.

Презентация:



Advertisements
Похожие презентации
Взаимодействие процессов: сокеты.
Advertisements

Механизм сокетов Средства межпроцессного взаимодействия ОС Unix, представленные в системе IPС, решают проблему взаимодействия процессов, выполняющихся.
СОКЕТЫ. СОКЕТ Сокет – программный интерфейс для обеспечения обмена данными между процессами. Впервые socket API появилась в BSD Unix. Описан в POSIX В.
Корпоративные системы Лекция 3. Реализация архитектуры «Клиент- сервер» с использованием механизма сокетов.
TECHNOLOGIES Программирование Socket'ов Socket (гнездо, разъем) - абстрактное программное понятие, используемое для обозначения в прикладной.
СЕТЕВОЕ ПРОГРАММИРОВАНИЕ В LINUX. Со́кеты Со́кеты (англ. socket углубление, гнездо, разъём) название программного интерфейса для обеспечения обмена данными.
Сокеты в Perl и PHP. Сокеты в Perl Сокеты являются «конечными пунктами» в процессе обмена данными. Одни типы сокетов обеспечивают надежный обмен данными,
СОКЕТЫ -2 РАБОТА СЕРВЕРА Стандартная схема работы плоха тем, что одновременно обслуживается только один клиент ! Это приводит к задержкам в работе сети.
Сокеты Сети и системы телекоммуникаций Созыкин А.В.
Сети ЭВМ и телекоммуникации. Состояния сеанса TCP CLOSED Начальное состояние узла LISTEN Сервер ожидает запросов установления соединения от клиента SYN-SENT.
Стек протоколов TCP/IP сетевые адаптеры, модемы, кабельная система; формирование пакетов, целостность данных целостность пакетов, потоковая передача Межузловой.
Реализация взаимодействия процессов. Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные.
Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Технология клиент-сервер Архитектура распределённой вычислительной системы, в которой.
Система межпроцессного взаимодействия IPC. Общие концепции #include key_t ftok ( char * filename, char proj ) filename строка, cодержащая имя файла proj.
Реализация взаимодействия процессов. Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные.
Низкоуровневые операции в ИС. Сокеты в C#. Понятие сокета Если требуется получить доступ к сетевым операциям низкого уровня, в программе следует использовать.
2.Система межпроцессного взаимодействия IPC 2.1.Состав, общие концепции 2.2.Очередь сообщений 2.3.Разделяемая память 2.4.Массив семафоров Взаимодействие.
ПАРАМЕТРЫ СОКЕТА Методическое пособие по дисциплине «Программное обеспечение компьютерных сетей и информационных систем»
Реализация взаимодействия процессов. Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные.
Интерфейс сокетов. Интерфейс прикладной программы (API) представляет собой просто набор функций (интерфейс), использующийся программистами для разработки.
Транксрипт:

3. Механизм сокетов 3.1. Общие концепции 3.2. Интерфейсные функции для работы с сокетом Создание сокета Связывание и установление соединения Приём и передача данных Завершение работы с сокетом 3.3. Схема работы с сокетами С установлением соединения Без установления соединения 3.4.Пример. Работа с локальными сокетами Взаимодействие процессов

Механизм сокетов Сокеты (sockets) унифицированное средство взаимодействия процессов (UNIX BSD 4.2). Типы сокетов Коммуникационный домен В сети В пределах локального компьютера Виртуальный канал Датаграммное соединение AF_UNIX AF_INET …

Создание сокета #include int socket ( int domain, int type, int protocol ) ; domain коммуникационный домен: AF_UNIX AF_INET type тип сокета: SOCK_STREAM виртуальный канал SOCK_DGRAM датаграммы protocol протокол: 0 автоматический выбор протокола IPPROTO_TCP протокол TCP (AF_INET) IPPROTO_UDP протокол UDP (AF_INET) Необходимые заголовочные файлы и прототип Параметры

Связывание #include int bind ( int sockfd, struct sockaddr * myaddr, int addrlen ) ; sockfd дескриптор сокета myaddr указатель на структуру, содержащую адрес сокета #include struct sockaddr_un { short sun_family ;/* == AF_UNIX */ char sun_path [ 108 ] ; } ; Структура адреса для домена AF_UNIX Необходимые заголовочные файлы и прототип Параметры

Связывание #include int bind ( int sockfd, struct sockaddr * myaddr, int addrlen ) ; #include struct sockaddr_in { short sin_family ;/* == AF_INET */ u_short sin_port ;/* port number */ struct in_addr sin_addr ;/* host IP address */ char sin_zero [ 8 ] ;/* not used */ } ; Структура адреса для домена AF_INET sockfd дескриптор сокета myaddr указатель на структуру, содержащую адрес сокета Необходимые заголовочные файлы и прототип Параметры

Связывание #include int bind ( int sockfd, struct sockaddr * myaddr, int addrlen ) ; addrlen размер структуры sockaddr («доменный» адрес сокета). В случае успешного связывания bind возвращает 0, в случае ошибки –1. Необходимые заголовочные файлы и прототип Параметры Возвращаемое значение

socket () bind () сервер Предварительное установление соединения (тип сокета виртуальный канал или датаграмма) socket () bind () listen () while (…) accept () recv ()send () shutdown () close () клиент socket () bind () connect () recv ()send () shutdown () close () клиент

Сокеты без предварительного соединения (тип сокета датаграмма) процесс 1 socket () bind () recvfrom ()sendto () shutdown () close () процесс 2 socket () bind () recvfrom ()sendto () shutdown () close () socket () bind () процесс N

Запрос на соединение #include int connect ( int sockfd, struct sockaddr * serv_addr, int addrlen ) ; sockfd дескриптор сокета serv_addr указатель на структуру, содержащую адрес сокета, с которым производится соединение, в формате, который мы обсуждали выше addrlen реальная длина структуры В случае успешного связывания функция возвращает 0, в случае ошибки –1. Код ошибки заносится в errno. Необходимые заголовочные файлы и прототип Параметры Возвращаемое значение

Прослушивание сокета #include int listen (int sockfd, int backlog); sockfd дескриптор сокета backlog максимальный размер очереди запросов на соединение В случае успешного связывания функция возвращает 0, в случае ошибки –1. Код ошибки заносится в errno. Необходимые заголовочные файлы и прототип Параметры Возвращаемое значение

Подтверждение соединения #include int accept ( int sockfd, struct sockaddr * addr, int * addrlen ) ; sockfd дескриптор сокета addr указатель на структуру, в которой возвращается адрес клиентского сокета, с которым установлено соединение (если адрес клиента не интересует, передается NULL). addrlen возвращается реальная длина этой структуры. максимальный размер очереди запросов на соединение. Возвращает дескриптор нового сокета, соединенного с сокетом клиентского процесса. Необходимые заголовочные файлы и прототип Параметры Возвращаемое значение

Прием и передача данных int send ( int sockfd, const void * msg, int len, unsigned int flags ) ; int recv ( int sockfd, void * buf, int len, unsigned int flags ) ; #include sockfd дескриптор сокета, через который передаются данные msg сообщение len длина сообщения buf указатель на буфер для приема данных len первоначальная длина буфера Необходимые заголовочные файлы и прототип Параметры

Прием и передача данных int send ( int sockfd, const void * msg, int len, unsigned int flags ) ; int recv ( int sockfd, void * buf, int len, unsigned int flags ) ; #include flags может содержать комбинацию специальных опций. MSG_OOB флаг сообщает ОС, что процесс хочет осуществить прием/передачу экстренных сообщений. MSG_PEEK При вызове recv () процесс может прочитать порцию данных, не удаляя ее из сокета. Последующий вызов recv вновь вернет те же самые данные. Необходимые заголовочные файлы и прототип Параметры

Прием и передача данных int send ( int sockfd, const void * msg, int len, unsigned int flags ) ; int recv ( int sockfd, void * buf, int len, unsigned int flags ) ; #include Функция возвращает количество переданных байт в случае успеха и –1 в случае неудачи. Код ошибки при этом устанавливается в errno. В случае успеха функция возвращает количество считанных байт, в случае неудачи –1. Необходимые заголовочные файлы и прототип Возвращаемое значение

Прием и передача данных Read() Write() В качестве параметра этим функциям передается дескриптор сокета.

Прием и передача данных int sendto ( int sockfd, const void * msg, int len, unsigned int flags, const struct sockaddr * to, int tolen ) ; int recvfrom ( int sockfd, void * buf, int len, unsigned int flags, struct sockaddr * from, int * fromlen ) ; #include Такие же, как и у рассмотренных раньше указатель на структуру, содержащую адрес получателя указатель на структуру с адресом отправителя размер структуры to размер структуры from Такие же, как и у рассмотренных раньше Необходимые заголовочные файлы и прототип

Завершение работы с сокетом #include int shutdown ( int sockfd, int mode ) ; sockfd дескриптор сокета mode режим закрытия соединения = 0, сокет закрывается для чтения = 1, сокет закрывается для записи = 2, сокет закрывается и для чтения, и для записи int close (int fd) ; (закрытие сокета) (закрытие соединения) Необходимые заголовочные файлы и прототип Параметры

Схема работы с сокетами с установлением соединения Серверный сокет Клиентский сокет socket bind listen accept sendrecv shutdown close socket bind connect sendrecv shutdown close

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

AF_UNIX Пример. Работа с локальными сокетами #include #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 ) { printf ( client: error writing socket!\n ) ; return 0 ; } if ( recvfrom ( sockfd, buf, BUFLEN, 0, NULL, 0 )

printf ( "client: server answered: %s\n", buf ) ; if ( quitting ) break ; printf ( type the string: ) ; }/* while */ close ( sockfd ) ; return 0 ; }/* if (!is_server), клиент */ …

... while ( 1 ) { /* получаем строку от клиента и выводим на печать */ party_len = sizeof ( party_addr ) ; if ( recvfrom ( sockfd, buf, BUFLEN, 0, ( struct sockaddr * ) & party_addr, & party_len ) < 0 ) { printf ( server: error reading socket! ) ; return 0 ; } printf ( server: received from client: %s \n, buf ) ; /* не пора ли выходить? */ quitting = ( ! strcmp ( buf, quit ) ) ; if ( quitting ) strcpy ( buf, quitting now! ) ; else if ( ! strcmp ( buf, ping! ) ) strcpy ( buf, pong! ) ; else strcpy ( buf, wrong string! ) ; …

... /* посылаем ответ */ if ( sendto ( sockfd, buf, strlen ( buf ) + 1, 0, ( struct sockaddr * ) & party_addr, party_len ) != strlen ( buf ) + 1 ) { printf ( server: error writing socket!\n ) ; return 0 ; } if ( quitting ) break ; } /* while ( 1 ) */ close ( sockfd ) ; return 0 ; }

AF_INET ( GET / ) Пример. Работа с локальными сокетами #include #define PORTNUM 8080 #define BACKLOG 5 #define BUFLEN 80 #define FNFSTR "404 Error File Not Found " #define BRSTR "Bad Request "

int main ( int argc, char ** argv ) { struct sockaddr_in own_addr, party_addr ; int sockfd, newsockfd, filefd ; int party_len ; char buf [ BUFLEN ] ; int len ; int i ; /* создаем сокет */ if ( ( sockfd = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { printf ( can't create socket\n ) ; return 0 ; } …

/* связываем сокет */ memset ( & own_addr, 0, sizeof ( own_addr ) ) ; own_addr. sin_family = AF_INET ; own_addr. sin_addr. s_addr = INADDR_ANY ; own_addr. sin_port = htons ( PORTNUM ) ; if ( bind ( sockfd, ( struct sockaddr * ) & own_addr, sizeof ( own_addr ) ) < 0 ) { printf ( can't bind socket! ) ; return 0 ; } /* начинаем обработку запросов на соединение */ if ( listen ( sockfd, BACKLOG ) < 0 ) { printf ( can't listen socket! ) ; return 0 ; } …

while ( 1 ) { memset ( & party_addr, 0, sizeof ( party_addr ) ) ; party_len = sizeof ( party_addr ) ; /* создаем соединение */ if ( ( newsockfd = accept ( sockfd, ( struct sockaddr * ) & party_addr, & party_len ) ) < 0 ) { printf ( error accepting connection! ) ; return 0 ; } if ( ! fork () ) { /*это сын, он обрабатывает запрос и посылает ответ*/ close ( sockfd ) ; /* этот сокет сыну не нужен */ if ( ( len = recv ( newsockfd, & buf, BUFLEN, 0 ) ) < 0 ) { printf ( error reading socket! ) ; return 0 ; } …

/* разбираем текст запроса */ printf ( "received: %s \n", buf ) ; if ( strncmp ( buf, "GET /", 5 ) ) { /* плохой запрос! */ if ( send ( newsockfd, BRSTR, strlen ( BRSTR ) + 1, 0 ) != strlen ( BRSTR ) + 1 ) { printf ( error writing socket! ) ; return 0 ; } shutdown ( newsockfd, 1 ) ; close ( newsockfd ) ; return 0 ; } …

for ( i =5; buf [ i ] && ( buf [ i ] > ) ; i++ ) ; buf [ i ] = 0 ; /* открываем файл */ if ( ( filefd = open ( buf + 5, O_RDONLY ) ) < 0) { /* нет файла! */ if ( send ( newsockfd, FNFSTR, strlen ( FNFSTR ) + 1, 0) != strlen ( FNFSTR ) + 1 ) { printf ( error writing socket! ) ; return 0 ; } shutdown ( newsockfd, 1 ) ; close ( newsockfd ) ; return 0 ; } …

/* читаем из файла порции данных и посылаем их клиенту */ while ( len = read ( filefd, & buf, BUFLEN ) ) if ( send ( newsockfd, buf, len, 0 ) < 0 ) { printf ( error writing socket! ) ; return 0 ; } close ( filefd ) ; shutdown ( newsockfd, 1 ) ; close ( newsockfd ) ; return 0 ; } /* процесс отец. Он закрывает новый сокет и продолжает прослушивать старый */ close ( newsockfd ) ; }/* while (1) */ }