- •Сетевое программирование
- •Материал этих методических указаний предпологает использование языка cи, возможностей ос Linux, cистемных вызовов этой операционной системы, и ее библиотек.
- •Краткие теоретические сведения.
- •1.1 Создание socket'а
- •1.2 Связывание socket'а
- •1.3 Ожидание установления связи
- •1.4 Запрос на установление соединения
- •1.5 Прием запроса на установление связи
- •1.6 Формирование адреса узла сети
- •1.7 Функции обмена данными
- •1.8 Посылка данных
- •Получение данных
- •Функции закрытия связи
- •Цикл лабораторных работ «Сетевое программирование на базе
- •Примеры использования socket-интерфейса для организации клиент – серверного взаимодействия
- •Программа-сервер
- •Программа-клиент
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
- •Возвращаемое значение
- •Прототип
- •Описание
Прототип
#include <sys/socket.h>
int listen(int s, int backlog);
Описание
Параметр backlog означает резерв - сколько ожидающих соединений можете иметь до того, как ядро начнёт отбрасывать новые. Так что, как только придёт новое соединение, необходимо быстро принять (accept()) его, чтобы не переполнять резерв. Можно установить 10 или около того, и если при высокой нагрузке, ваши клиенты начнут получать “Connection refused” (“Соединение отвергнуто”), следует установить побольше.
Перед вызовом listen() сервер должен вызвать bind() чтобы подключиться к определённому номеру порта. Клиенты будут подключаться к этому порту на IP адресе сервера.
Возвращаемое значение
Возвращает 0 при успехе или -1 в случае ошибки (errno устанавливается соответственно).
Пример
struct addrinfo hints, *res; int sockfd;
// сначала заполняем адресные структуры с помощью getaddrinfo(): memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // использовать либо IPv4 либо IPv6
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // заполнить мой IP для меня getaddrinfo(NULL, "3490", &hints, &res);
// создать сокет:
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
// связать с портом, переданным getaddrinfo(): bind(sockfd, res->ai_addr, res->ai_addrlen); listen(sockfd, 10);
// теперь слушает
// где-то дальше есть цикл accept()
perror(), strerror()
Распечатывают ошибку как читаемую строку
Прототип
.
#include <stdio.h>
#include <string.h> // для strerror()
Void perror(const char *s); char *strerror(int errnum);
Описание
Очень много функций при ошибке возвращают -1 и записывают в errno некоторое число, и было бы удобно, если бы можно было распечатать в понятной форме.
И perror() это делает. Если необходимо добавить описание перед сообщением об ошибке, следует передать указатель на него в параметре s (можно оставить s как NULL и ничего дополнительно не напечатается.)
Эта функция берёт значение errno, вроде ECONNRESET, и печатает его как “Connection reset by peer.”
Функция strerror() подобна perror(), за исключением того, что она возвращает указатель на строку с сообщением об ошибке для заданного параметром errnum значения (обычно переменная передаётся в errno.)
Возвращаемое значение
strerror() возвращает указатель на строку с сообщением об ошибке.
Пример
int s;
s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) { // ошибка вышла
// печатает "socket error: " + сообщение об ошибке:
perror("socket error");
}
// подобно:
if (listen(s, 10) == -1) {
// это печатает "an error: " + сообщение об ошибке из errno:
printf("an error: %s\n", strerror(errno));
}
recv(), recvfrom()
Принимают данные из сокета.
Прототип
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int s, void *buf, size_t len, int flags); ssize_t recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
