В этой главе описываются основные функции сокетов, необходимые для написания полноценного TCP-клиента и сервера.
Следующая диаграмма показывает полное взаимодействие клиента и сервера —
Функция розетки
Чтобы выполнить сетевой ввод-вывод, первое, что должен сделать процесс, это вызвать функцию сокета, указав тип требуемого протокола связи и семейство протоколов и т. Д.
#include <sys/types.h> #include <sys/socket.h> int socket (int family, int type, int protocol);
Этот вызов возвращает дескриптор сокета, который вы можете использовать в последующих системных вызовах или -1 при ошибке.
параметры
family — определяет семейство протоколов и является одной из констант, показанных ниже —
семья | Описание |
---|---|
AF_INET | Протоколы IPv4 |
AF_INET6 | Протоколы IPv6 |
AF_LOCAL | Доменные протоколы Unix |
AF_ROUTE | Маршрутные розетки |
AF_KEY | Кет розетка |
Эта глава не охватывает другие протоколы, кроме IPv4.
type — определяет тип сокета, который вы хотите. Может принимать одно из следующих значений:
Тип | Описание |
---|---|
SOCK_STREAM | Потоковая розетка |
SOCK_DGRAM | Гнездо датаграммы |
SOCK_SEQPACKET | Последовательный пакетный сокет |
SOCK_RAW | Сырое гнездо |
протокол — Аргумент должен быть установлен на конкретный тип протокола, указанный ниже, или 0, чтобы выбрать системное значение по умолчанию для данной комбинации семейства и типа —
протокол | Описание |
---|---|
IPPROTO_TCP | Транспортный протокол TCP |
IPPROTO_UDP | Транспортный протокол UDP |
IPPROTO_SCTP | Транспортный протокол SCTP |
Функция подключения
Функция соединения используется TCP-клиентом для установления соединения с TCP-сервером.
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Этот вызов возвращает 0, если он успешно подключается к серверу, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
serv_addr — это указатель на структуру sockaddr, которая содержит IP-адрес и порт назначения.
-
addrlen — установить его в sizeof (struct sockaddr).
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
serv_addr — это указатель на структуру sockaddr, которая содержит IP-адрес и порт назначения.
addrlen — установить его в sizeof (struct sockaddr).
Функция связывания
Функция bind назначает сокету адрес локального протокола. В интернет-протоколах адрес протокола представляет собой комбинацию либо 32-битного IPv4-адреса, либо 128-битного IPv6-адреса вместе с 16-битным номером порта TCP или UDP. Эта функция вызывается только TCP-сервером.
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, struct sockaddr *my_addr,int addrlen);
Этот вызов возвращает 0, если он успешно связывается с адресом, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
my_addr — это указатель на структуру sockaddr, которая содержит локальный IP-адрес и порт.
-
addrlen — установить его в sizeof (struct sockaddr).
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
my_addr — это указатель на структуру sockaddr, которая содержит локальный IP-адрес и порт.
addrlen — установить его в sizeof (struct sockaddr).
Вы можете поставить свой IP-адрес и порт автоматически
Значение 0 для номера порта означает, что система выберет произвольный порт, а значение INADDR_ANY для IP-адреса означает, что IP-адрес сервера будет назначен автоматически.
server.sin_port = 0; server.sin_addr.s_addr = INADDR_ANY;
ПРИМЕЧАНИЕ. — Все порты ниже 1024 зарезервированы. Вы можете установить порт выше 1024 и ниже 65535, если только они не используются другими программами.
Функция прослушивания
Функция прослушивания вызывается только TCP-сервером и выполняет два действия:
-
Функция listen преобразует неподключенный сокет в пассивный сокет, указывая, что ядро должно принимать входящие запросы на подключение, направленные на этот сокет.
-
Второй аргумент этой функции указывает максимальное количество соединений, которое ядро должно поставить в очередь для этого сокета.
Функция listen преобразует неподключенный сокет в пассивный сокет, указывая, что ядро должно принимать входящие запросы на подключение, направленные на этот сокет.
Второй аргумент этой функции указывает максимальное количество соединений, которое ядро должно поставить в очередь для этого сокета.
#include <sys/types.h> #include <sys/socket.h> int listen(int sockfd,int backlog);
Этот вызов возвращает 0 в случае успеха, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
отставание — это количество разрешенных соединений.
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
отставание — это количество разрешенных соединений.
Функция принятия
Функция принятия вызывается сервером TCP для возврата следующего завершенного соединения с начала очереди завершенных соединений. Подпись звонка выглядит следующим образом —
#include <sys/types.h> #include <sys/socket.h> int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
Этот вызов возвращает неотрицательный дескриптор в случае успеха, в противном случае он возвращает -1 при ошибке. Предполагается, что возвращаемый дескриптор является дескриптором сокета клиента, и все операции чтения-записи будут выполняться на этом дескрипторе для связи с клиентом.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
cliaddr — это указатель на структуру sockaddr, которая содержит IP-адрес и порт клиента.
-
addrlen — установить его в sizeof (struct sockaddr).
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
cliaddr — это указатель на структуру sockaddr, которая содержит IP-адрес и порт клиента.
addrlen — установить его в sizeof (struct sockaddr).
Функция отправки
Функция отправки используется для отправки данных через потоковые сокеты или СОЕДИНЕННЫЕ сокеты датаграмм. Если вы хотите отправлять данные через несоединенные дейтаграммы, вы должны использовать функцию sendto ().
Вы можете использовать системный вызов write () для отправки данных. Его подпись выглядит следующим образом —
int send(int sockfd, const void *msg, int len, int flags);
Этот вызов возвращает количество отправленных байтов, в противном случае он вернет -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
msg — это указатель на данные, которые вы хотите отправить.
-
len — это длина данных, которые вы хотите отправить (в байтах).
-
флаги — он установлен в 0.
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
msg — это указатель на данные, которые вы хотите отправить.
len — это длина данных, которые вы хотите отправить (в байтах).
флаги — он установлен в 0.
Функция recv
Функция recv используется для получения данных через потоковые сокеты или СОЕДИНЕННЫЕ сокеты датаграмм. Если вы хотите получать данные через сокеты UNCONNECTED дейтаграммы, вы должны использовать recvfrom ().
Вы можете использовать системный вызов read () для чтения данных. Этот вызов объясняется в главе вспомогательных функций.
int recv(int sockfd, void *buf, int len, unsigned int flags);
Этот вызов возвращает количество байтов, считанных в буфер, в противном случае он вернет -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
buf — это буфер для чтения информации.
-
len — это максимальная длина буфера.
-
флаги — он установлен в 0.
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
buf — это буфер для чтения информации.
len — это максимальная длина буфера.
флаги — он установлен в 0.
Функция sendto
Функция sendto используется для отправки данных через несвязанные гнезда дейтаграмм. Его подпись выглядит следующим образом —
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
Этот вызов возвращает количество отправленных байтов, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
msg — это указатель на данные, которые вы хотите отправить.
-
len — это длина данных, которые вы хотите отправить (в байтах).
-
флаги — он установлен в 0.
-
to — это указатель на структуру sockaddr для хоста, на который должны быть отправлены данные.
-
tolen — устанавливается в sizeof (struct sockaddr).
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
msg — это указатель на данные, которые вы хотите отправить.
len — это длина данных, которые вы хотите отправить (в байтах).
флаги — он установлен в 0.
to — это указатель на структуру sockaddr для хоста, на который должны быть отправлены данные.
tolen — устанавливается в sizeof (struct sockaddr).
Функция recvfrom
Функция recvfrom используется для получения данных из неподключенных сокетов дейтаграмм.
int recvfrom(int sockfd, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen);
Этот вызов возвращает количество байтов, прочитанных в буфер, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
buf — это буфер для чтения информации.
-
len — это максимальная длина буфера.
-
флаги — он установлен в 0.
-
from — это указатель на структуру sockaddr для хоста, на котором должны быть прочитаны данные.
-
fromlen — устанавливается в sizeof (struct sockaddr).
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
buf — это буфер для чтения информации.
len — это максимальная длина буфера.
флаги — он установлен в 0.
from — это указатель на структуру sockaddr для хоста, на котором должны быть прочитаны данные.
fromlen — устанавливается в sizeof (struct sockaddr).
Функция закрытия
Функция закрытия используется для закрытия связи между клиентом и сервером. Его синтаксис выглядит следующим образом —
int close( int sockfd );
Этот вызов возвращает 0 в случае успеха, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
Функция выключения
Функция выключения используется для постепенного закрытия связи между клиентом и сервером. Эта функция дает больше контроля по сравнению с функцией закрытия . Ниже приведен синтаксис выключения —
int shutdown(int sockfd, int how);
Этот вызов возвращает 0 в случае успеха, в противном случае он возвращает -1 в случае ошибки.
параметры
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
-
как — поставить одно из чисел —
-
0 — указывает, что прием не разрешен,
-
1 — указывает, что отправка запрещена, и
-
2 — указывает, что отправка и получение не разрешены. Когда how имеет значение 2, это то же самое, что close ().
-
sockfd — это дескриптор сокета, возвращаемый функцией сокета.
как — поставить одно из чисел —
0 — указывает, что прием не разрешен,
1 — указывает, что отправка запрещена, и
2 — указывает, что отправка и получение не разрешены. Когда how имеет значение 2, это то же самое, что close ().
Функция выбора
Функция выбора указывает, какой из указанных файловых дескрипторов готов к чтению, готов к записи или имеет ожидающее состояние ошибки.
Когда приложение вызывает recv или recvfrom , оно блокируется до тех пор, пока данные не поступят в этот сокет. Приложение может выполнять другую полезную обработку, когда входящий поток данных пуст. Другая ситуация, когда приложение получает данные из нескольких сокетов.
Вызов recv или recvfrom для сокета, у которого нет данных во входной очереди, предотвращает немедленный прием данных из других сокетов. Вызов функции select решает эту проблему, позволяя программе опрашивать все дескрипторы сокетов, чтобы узнать, доступны ли они для неблокирующих операций чтения и записи.
Ниже приведен синтаксис выбора —
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
Этот вызов возвращает 0 в случае успеха, в противном случае он возвращает -1 в случае ошибки.
параметры
-
nfds — указывает диапазон файловых дескрипторов для тестирования. Функция select () проверяет файловые дескрипторы в диапазоне от 0 до nfds-1
-
readfds — указывает на объект типа fd_set, который при вводе указывает файловые дескрипторы, которые необходимо проверить на готовность к чтению, а при выводе указывает, какие файловые дескрипторы готовы к чтению. Это может быть NULL, чтобы указать пустой набор.
-
writefds — указывает на объект типа fd_set, который при вводе указывает файловые дескрипторы, которые необходимо проверить на готовность к записи, а при выводе указывает, какие файловые дескрипторы готовы к записи. Это может быть NULL, чтобы указать пустой набор.
-
Кроме того, он указывает на объект типа fd_set, который при вводе указывает файловые дескрипторы, которые должны быть проверены на наличие ожидающих условий ошибки, а на выходе указывает, какие дескрипторы файлов имеют ожидающие условия ошибки. Это может быть NULL, чтобы указать пустой набор.
-
timeout — указывает на структуру timeval, которая указывает, как долго вызов select должен опрашивать дескрипторы для доступной операции ввода-вывода. Если значение тайм-аута равно 0, то выбор вернется немедленно. Если аргумент тайм-аута равен NULL, select будет блокироваться, пока хотя бы один дескриптор файла / сокета не будет готов к доступной операции ввода-вывода. В противном случае команда select возвращается после истечения времени ожидания ИЛИ, когда хотя бы один дескриптор файла / сокета готов к операции ввода-вывода.
nfds — указывает диапазон файловых дескрипторов для тестирования. Функция select () проверяет файловые дескрипторы в диапазоне от 0 до nfds-1
readfds — указывает на объект типа fd_set, который при вводе указывает файловые дескрипторы, которые необходимо проверить на готовность к чтению, а при выводе указывает, какие файловые дескрипторы готовы к чтению. Это может быть NULL, чтобы указать пустой набор.
writefds — указывает на объект типа fd_set, который при вводе указывает файловые дескрипторы, которые необходимо проверить на готовность к записи, а при выводе указывает, какие файловые дескрипторы готовы к записи. Это может быть NULL, чтобы указать пустой набор.
Кроме того, он указывает на объект типа fd_set, который при вводе указывает файловые дескрипторы, которые должны быть проверены на наличие ожидающих условий ошибки, а на выходе указывает, какие дескрипторы файлов имеют ожидающие условия ошибки. Это может быть NULL, чтобы указать пустой набор.
timeout — указывает на структуру timeval, которая указывает, как долго вызов select должен опрашивать дескрипторы для доступной операции ввода-вывода. Если значение тайм-аута равно 0, то выбор вернется немедленно. Если аргумент тайм-аута равен NULL, select будет блокироваться, пока хотя бы один дескриптор файла / сокета не будет готов к доступной операции ввода-вывода. В противном случае команда select возвращается после истечения времени ожидания ИЛИ, когда хотя бы один дескриптор файла / сокета готов к операции ввода-вывода.
Возвращаемое значение из select — это количество дескрипторов, указанных в наборах дескрипторов файлов, которые готовы к вводу / выводу. Если предел времени, указанный в поле времени ожидания, достигнут, выберите return 0. Существуют следующие макросы для управления набором дескрипторов файлов:
-
FD_CLR (fd, & fdset) — очищает бит для файлового дескриптора fd в наборе файловых дескрипторов fdset.
-
FD_ISSET (fd, & fdset) — возвращает ненулевое значение, если бит для дескриптора файла fd установлен в наборе дескрипторов файла, на который указывает fdset , и 0 в противном случае.
-
FD_SET (fd, & fdset) — устанавливает бит для дескриптора файла fd в наборе дескрипторов файла fdset.
-
FD_ZERO (& fdset) — Инициализирует набор файловых дескрипторов fdset, чтобы иметь нулевые биты для всех файловых дескрипторов.
FD_CLR (fd, & fdset) — очищает бит для файлового дескриптора fd в наборе файловых дескрипторов fdset.
FD_ISSET (fd, & fdset) — возвращает ненулевое значение, если бит для дескриптора файла fd установлен в наборе дескрипторов файла, на который указывает fdset , и 0 в противном случае.
FD_SET (fd, & fdset) — устанавливает бит для дескриптора файла fd в наборе дескрипторов файла fdset.
FD_ZERO (& fdset) — Инициализирует набор файловых дескрипторов fdset, чтобы иметь нулевые биты для всех файловых дескрипторов.
Поведение этих макросов не определено, если аргумент fd меньше 0 или больше или равен FD_SETSIZE.