Предыдущая | Оглавление | Следующая |
Принять входящее соединение
#include <sys/types.h>
#include <sys/socket.h>
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
Когда ты создал сокет типа SOCK_STREAM и настроил его на ожидание соединений с помощью listen(), вызови accept(), чтобы получить новый дескриптор сокета для дальнейшего взаимодействия с соединившимся клиентом.
Старый сокет - который ждет соединений - продолжает ждать, и для него можно опять вызывать accept().
s |
Ожидающий сокет. |
addr | Сюда возвращается адрес соединившегося клиента. |
addrlen | Сюда возвращается sizeof() структуры, возвращенной в addr. Если ты наверняка получаешь struct sockaddr_in, его можно спокойно проигнорировать. |
accept() блокирует, и ты можешь использовать select(), чтобы узнать, готов ли слушающий сокет "к чтению". На самом деле, это значит, что у него есть новое соединение! Также можно установить флаг O_NONBLOCK с помощью fcntl(), и он не будет блокировать, возвращая вместо этого -1 и сохраняя EWOULDBLOCK в errno.
Дескриптор сокета, возвращаемый функцией accept(), открыт и соединен с удаленным хостом. Его нужно закрыть с помощью close(), когда он будет не нужен.
accept() возвращает новый дескриптор сокета, или -1 при ошибке, сохраняя ее номер в errno.
int s, s2; struct sockaddr_in myaddr, remoteaddr; socklen_t remoteaddr_len; myaddr.sin_family = AF_INET; myaddr.sin_port = htons(3490); // порт соединения myaddr.sin_addr.s_addr = INADDR_ANY; // автоматический выбор IP-адреса s = socket(PF_INET, SOCK_STREAM, 0); bind(s, (struct sockaddr*)myaddr, sizeof(myaddr)); listen(s, 10); // сделать s слушающим (серверным) сокетом for(;;) { s2 = accept(s, &remoteaddr, &remoteaddr_len); // теперь можно использовать send() и recv() // для обмена данными с клиентом через сокет s2 } |
Предыдущая | Оглавление | Следующая |