
- •2. Функции для работы с сокетами
- •3. Схема работы сервера и клиента с предварительным установлением связи
- •4. Пример сервера и клиента
- •5. Цели и задачи
- •6. Порядок выполнения лабораторной работы
- •7. Варианты заданий (1-15)
- •8. Варианты заданий (16-30)
- •9. Варианты заданий (31-45)
- •10. Варианты заданий (46-60)
Лабораторная работа 8
Сокеты
1. Сокеты
2. Функции для работы с сокетами
3. Схема работы сервера и клиента с предварительным установлением связи
4. Пример сервера и клиента
5. Цели и задачи
6. Порядок выполнения лабораторной работы
7. Варианты заданий (1-15)
8. Варианты заданий (16-30)
9. Варианты заданий (31-45)
10. Варианты заданий (46-60)
1. Сокеты
Взаимодействие процессов на основе сокетов основано на модели "клиент-сервер". Процесс-сервер "слушает" сокет, а процесс-клиент устанавливает связь с сокетом сервера, зная его адрес. Если связь устанавливается, сервер узнает адрес сокета клиента, после чего возможен двусторонний обмен информацией между сервером и клиентом. Ядро операционной системы обеспечивает установку соединения и маршрутизацию данных от клиента к серверу.
Сокеты с общими коммуникационными свойствами, такими как способ именования и протокольный формат адреса, группируются в домены. Наиболее часто используемыми являются "домен системы UNIX" (AF_UNIX) для процессов, которые взаимодействуют через программные гнезда в пределах одного компьютера, и "домен Internet"(AF_INET) для процессов, которые взаимодействуют в сети посредством семейства протоколов TCP/IP.
Выделяются два типа программных сокетов – сокеты потока (SOCK_STREAM) и сокеты датаграмм (SOCK_DGRAM). Для сокетов потока предварительное установление соединения является обязательным. При использовании сокетов с предварительным соединением обеспечивается передача данных от клиента к серверу в виде непрерывного потока байтов с гарантией доставки. При этом до начала передачи данных должно быть установлено соединение, которое поддерживается до конца коммуникационной сессии. Сокеты датаграмм не гарантируют абсолютной надежной, последовательной доставки сообщений и отсутствия дубликатов пакетов данных - датаграмм. При использовании сокетов датаграмм не требуется предварительное установление соединения.
Операционная система сама обеспечивает подходящий протокол для каждой допустимой комбинации "домен-сокет". Например, протокол TCP используется по умолчанию для сокетов потока, а протокол UDP - для сокетов датаграмм.
2. Функции для работы с сокетами
Для использования следующих функций необходимо подключить заголовочные файлы sys/types.h и sys/socket.h.
int socket (int domain, int type, int protocol)
Функция создает сокет типа type (SOCK_STREAM – сокет потока, SOCK_DGRAM – сокет датаграмм) в коммуникационном домене domain (AF_UNIX – взаимодействие локальных процессов, AF_INET – взаимодействие удаленных процессов), работающий через протокол protocol (IPPROTO_TCP, IPPROTO_UDP). Если protocol равен 0 система сама выбирает протокол для сокета в соответствии с указанным доменом и типом сокета. Функция возвращает дескриптор сокета в случае успеха, либо -1 в случае неудачи.
int bind (int sockfd, struct sockaddr *addr, int addrlen)
Функция связывает сокет, обладающий дескриптором sockfd, с адресом, указанным в addr, addrlen – размер адреса в байтах. Функция возвращает 0 в случае успеха, либо -1 в случае неудачи.
Если сокет создан в домене AF_UNIX, его адрес определяется следующей структурой (заголовочный файл – sys/un.h).
struct sockaddr_un
{ short sun_family ; /*=AF_UNIX*/
char sun_path[108] ; /*имя файла*/
}
Если сокет создан в домене AF_INET, его адрес определяется следующей структурой (заголовочный файл – netinet/in.h).
struct sockaddr_in
{ short sin_family ; /*=AF_INET*/
u_short sin_port ; /*номер порта – адрес приложения*/ /*должен быть > 1025*/
struct in_addr sin_addr ; /*IP адрес хоста*/ /*INADDR_ANY = 0.0.0.0*/
}
int connect (int sockfd, struct sockaddr *servaddr, int addrlen)
Функция используется для предварительного установления связи. Функция создает виртуальный канал между сокетом, обладающим дескриптором sockfd, с сокетом, обладающим адресом servaddr, где addrlen – размер адреса servaddr в байтах. Функция возвращает 0 в случае успеха, либо -1 в случае неудачи. Функция connect вызывается клиентом, так как клиенту всегда известен адрес сервера, и в этом случае клиенту не нужно вызывать функцию bind.
int listen (int sockfd, int backlog)
Функция информирует систему о том, что сервер готов принимать запросы на установление связи через сокет с дескриптором sockfd. Параметр backlog определяет максимальное число запросов на установление предварительной связи, которые могут ожидать обработки сервером.
int accept (int sockfd, sockaddr *caddr, int *addrlen)
Функция извлекает запрос из очереди запросов на предварительное установление связи, поступивших на сокет sockfd и завершает создание виртуального канала со стороны сервера. В caddr система записывает адрес клиента, который послал данный запрос на установление предварительной связи, в addrlen – размер адреса клиента в байтах. В случае успеха функция возвращает дескриптор нового сокета, который и будет использоваться для связи с клиентом, тогда как сокет sockfd будет ожидать поступления других запросов на предварительное установление связи.
int send (int sockfd, void *msg, int len, int flags)
Функция посылает данные msg объемом len через сокет, обладающий дескриптором sockfd. Параметр flags может быть равен нулю или MSG_OOB, в последнем случае данные msg посылаются как экстренные данные (сокет датаграмм не поддерживает экстренные данные). В случае успеха функция возвращает количество посланных байт, либо -1 в случае неудачи. Функция используется для передачи данных, только если была выполнена операция предварительного установления связи с сервером. В противном случае можно использовать такую функцию.
int sendto (int sockfd, void *msg, int len, int flags, sockaddr *servaddr, int addrlen)
Функция sendto выполняет те же действия, что и функция send. Но данные посылается сокету с адресом servaddr, где addrlen – размер адреса servaddr в байтах.
int recv (int sockfd, void *msg, int maxlen, int flags)
Функция считывает данные максимального объема maxlen в msg из сокета, обладающего дескриптором sockfd. Параметр flags может быть равен нулю или MSG_PEEK, в последнем случае данные считываются, но не изымаются из сокета, т.е. они будут доступны и при повторном чтении. В случае успеха функция возвращает количество прочитанных байт, либо -1 в случае неудачи. Процесс, вызвавший функцию, останавливается до тех пор, пока данные не будут получены или не произойдет ошибка. Функция используется для получения данных, только если была выполнена операция предварительного установления связи. В противном случае можно использовать такую функцию.
int recvfrom (int sockfd, void *msg, int len, int flags, sockaddr *сaddr, socklen_t *addrlen)
Функция recvfrom выполняет те же действия, что и функция recv. Но здесь адрес отправителя данных записывается системой в сddr, в addrlen записывается размер адреса саddr в байтах.