Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция 8.docx
Скачиваний:
151
Добавлен:
17.06.2016
Размер:
133.75 Кб
Скачать
  1. Привязка сокета (bind())

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

int bind (sock, localaddr, addrlen)

int sock - дескриптор сокета struct sockaddr *localaddr - локальный сокет-адрес int addrlen - длина адреса

  1. Соединение клиента c сервером (connect())

int connect (sock, servaddr, addrlen)

int sock; - сокет-дескриптор struct sockaddr *servaddr; -адрес сервера int addrlen; - длина адреса

  1. установка сервера в режим "прослушивания" (listen())

Этот примитив указывает, что сервер готов к получению запросов на соединение. Параметр qlen указывает на максимальное число запросов, которое может быть установлено в режим ожидания обработки.

int listen (sock, qlen)

int sock; - сокет-дескриптор int qlen; - макс. число необработ. подсоединений

  1. Согласие сервера на соединение (accept())

Этот вызов используется сервером для ожидания запросов клиентов. Два последних параметра могут быть установлены в 0, кроме случаев, когда необходимо проверить идентичность клиента. Благодаря этому примитиву сервер дает клиенту понять, что его запрос принят. Примитив accept () возвращает новый сокет-дескриптор, который будет использован для обмена данными с клиентом. Для сервера имеется возможность создания порожденного процесса, который воспользуется вновь созданным дескриптором, в то время как порождающий процесс вновь перейдет в состояние ожидания соединения (accept ()) на сокете, открытом функцией socket ().

int accept (sock, addrdistant, addrlen)

int sock; - сокет-дескриптор struct sockaddr *addrdistant; - адрес телекоммуник. int *addrlen; - длина адреса

6.Примитивы считывания и записи read(), write(), send(), recv(), sendto(), recvfrom() Вызовы read () и write () используются также, как и для дескриптора файла. Вызовы send () и recv () имеют дополнительный аргумент, позволяющий, кроме всего прочего, посылать экспресс-данные. Вызовы send to () и recv from () используются для сокетов типа SOCK_DGRAM. Два дополнительных параметра позволяют уточ-нить адрес удаленного компьютера в случае sendto() и восстановить этот адрес в случае recvfrom().

7. Закрытие соединения

int close (sock)

int sock; - сокет-дескриптор

Перед закрытием ядро пытается переслать еще не посланные данные.

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

Листинг 1 - Пример кода сервера на языке Си

/* Код сервера на языке Си */

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#define port 1100

int main(void) {

struct sockaddr_in stSockAddr;/*структура для хранения адресной

информации*/

/*1.создаем «слушающий» сокет*/

int listenSocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

if (listenSocketFD == -1) {

perror("ошибка при создании сокета");

exit(EXIT_FAILURE);

}

/*обнуляем и заполняем структуру с адресной информацией */

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

stSockAddr.sin_family = PF_INET;

stSockAddr.sin_port = htons(port);

stSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);

/*2. Привязываем сокет к адресу*/

if (bind(listenSocketFD, (struct sockaddr*) &stSockAddr, sizeof (stSockAddr)) == -1) {

perror("Ошибка: связывания");

close(i32SocketFD);

exit(EXIT_FAILURE);

}

/*3. Переводим «слушающий» сокет в режим прослушивания сети*/

if (listen(listenSocketFD, 10) == -1) {

perror("Ошибка: прослушивания");

close(listenSocketFD);

exit(EXIT_FAILURE);

}

/*в бесконеном цикле создаем новое подключение и осуществляем взаимодействия с подключенными клиентами (Последовательно)*/

for (;;) {

/*4. Как только клиент попытается подключится к серверу функция accept() вернет дескриптор «рабочего» сокета, по которому будет осуществляться взаимодействие*/

int workConnectSocketFD = accept(listenSocketFD, 0, 0);

if (workConnectSocketFD < 0) {

perror("Ошибка: принятия подключения клиента");

close(listenSocketFD);

exit(EXIT_FAILURE);

}

/* выполнение операций чтения и записи при помощи

созданного рабочего сокета*/

shutdown(workConnectSocketFD, SHUT_RDWR);

/*Закрываем сокет*/

close(workConnectSocketFD);

}

return 0;

}

Соседние файлы в папке Лекции