На стороне сервера TCP-сокет, прослушивающий соединения, перейдет в читаемое состояние, когда клиентское соединение ожидает подтверждения. Вызовите accept()
, чтобы фактически принять соединение, и затем вы можете начать мониторинг состояний чтения / записи / закрытия в новом сокете TCP, возвращаемом accept()
. Это совершенно отдельный сокет, чем тот, который прослушивает соединения. Добавьте его в массив pollfds
, чтобы вы могли одновременно опрашивать его и прослушивающий сокет.
Попробуйте что-то вроде этого:
#include <vector>
std::vector<pollfds> fds;
{
pollfds listen_pf;
listen_pf.fd = listen_sd;
listen_pf.events = POLLIN;
listen_pf.push_back(listen_pf);
}
while (true) {
int ret = poll(fds.data(), fds.size(), 0);
if (ret < 0) {
exit(1);
}
size_t i = 0, size = fds.size();
while (i < size) {
if (fds[i].revents & POLLIN) {
if (fds[i].fd == listen_sd) {
// accept a pending client connection...
int client_sd = accept(listen_sd, NULL, NULL);
if (client_sd != -1) {
pollfds client_pf;
client_pf.fd = client_sd;
client_pf.events = POLLIN | POLLOUT | POLLRDHUP;
fds.push_back(client_pf);
}
}
else {
// read data from fds[i].fd as needed...
if (read fails) {
fds.erase(fds.begin()+i);
--size;
continue;
}
}
}
if (fds[i].revents & POLLOUT) {
// write pending data to fds[i].fd as needed ...
if (write fails) {
fds.erase(fds.begin()+i);
--size;
continue;
}
}
if (fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
if (fds[i].fd == listen_fd) {
exit(1);
}
else {
fds.erase(fds.begin()+i);
--size;
continue;
}
}
++i;
}
}
На стороне клиента TCP сокет, соединяющийся с сервером, перейдет в состояние записи для записи, когда connect()
успешен, и соединение с сервером полностью установлено и готово к вводу / выводу.