我正在尝试创建一个接受多个客户端的服务器。这是我的代码的一部分。我的服务器需要listen
到两个ports
。实现此目标的sockets
为fd_serv
和fd_comm
。
遗憾的是,使用select
和nonblock
文件描述符并未提供所需的输出。问题是select
accepts
第一个client
然后阻止,并且不会读取来自其他clients
的消息。
出于某种原因,如果我不使用usleep(100000)
命令,我的程序会成功接受但不会继续。
任何帮助表示感谢。
FD_ZERO(&set);
FD_SET(fd_serv, &set);
FD_SET(fd_comm, &set);
while (1)
{
if (select (max_fd + 1, &set, NULL, NULL, NULL) < 0)
{
perror ("select");
exit (EXIT_FAILURE);
}
for (i = 1; i < max_fd + 1; i++)
{
usleep(100000);
if (FD_ISSET (i, &set))
{
if (i == fd_serv) //Connection request on original socket.
{
new_serv = accept (fd_serv, (struct sockaddr *) &client_serv_addr, &sin_len_serv);
if (new_serv < 0){ perror ("accept"); exit (EXIT_FAILURE); }
fd_set_blocking(new_serv, 0);
FD_SET(new_serv, &set);
max_fd = max(max_fd, new_serv);
}
else if (i == fd_comm) //Connection request on original socket.
{
new_comm = accept (fd_comm, (struct sockaddr *) &client_comm_addr, &sin_len_comm);
if (new_comm < 0){ perror ("accept"); exit (EXIT_FAILURE); }
fd_set_blocking(new_comm, 0);
FD_SET (new_comm, &set);
max_fd = max(max_fd, new_comm);
}
else if (i == new_comm) //Activity on already connected socket
{
if (read_command(fd_comm, i, start_time) == 1)
{
close(i);
FD_CLR(i, &set);
return SHUTDOWN;
}
}
else if (i == new_serv) //Activity on already connected socket
{
read_service(i);
close(i);
FD_CLR(i, &set);
}
}
}
}
答案 0 :(得分:2)
你的问题在这里:
FD_ZERO(&set);
FD_SET(fd_serv, &set);
FD_SET(fd_comm, &set);
while (1)
{
[...]
您只需设置fd_set
一次,但fd_set
将被select()
调用修改,因此您需要在每次循环迭代时设置一次。试试这个:
while (1)
{
FD_ZERO(&set);
FD_SET(fd_serv, &set);
FD_SET(fd_comm, &set);
const int max_fd = (fd_serve > fd_comm) ? fd_serve : fd_comm;
[...]
...在select()
来电之后,您应该调用的唯一select()
相关内容是FD_ISSET()
。所有其他内容都毫无意义,因为您额外的FD_SET()
和FD_CLR()
来电正在修改fd_set
,您只需要通过FD_ZERO()
来电清除usleep(10000)
下一个while循环迭代的开始。
此外,作为附注:select()
来电应该消失 - 如果您正确调用select()
,则-webkit-clip-path: inset(0 0 90% 0);
之外的任意时间段内的睡眠都不会必要也不可取。