C 尝试从文件描述符读取活动时选择块

C 尝试从文件描述符读取活动时选择块,c,sockets,select,block,C,Sockets,Select,Block,我正在尝试创建一个接受多个客户端的服务器。这是我代码的一部分。我的服务器需要监听两个端口。实现这一点的套接字是fd_serv和fd_comm 不幸的是,使用选择和非块文件描述符无法提供所需的输出。问题在于select接受第一个客户端,然后阻塞,并且不从其他客户端读取消息 另外,由于某种原因,如果我不使用usleep(100000)命令,我的程序会成功接受,但不会继续 谢谢你的帮助 FD_ZERO(&set); FD_SET(fd_serv, &set); FD_SET(fd_co

我正在尝试创建一个接受多个客户端的服务器。这是我代码的一部分。我的服务器需要监听两个
端口
。实现这一点的
套接字是
fd_serv
fd_comm

不幸的是,使用
选择
非块
文件描述符无法提供所需的输出。问题在于
select
接受第一个
客户端
,然后阻塞,并且不从其他
客户端
读取消息

另外,由于某种原因,如果我不使用
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);
            }
        }
    }
}
FD_零点(&set);
FD_集(FD_serv,&SET);
FD_集合(FD_通信和集合);
而(1)
{
if(选择(max_fd+1,&set,NULL,NULL,NULL)<0)
{
佩罗(“选择”);
退出(退出失败);
}
对于(i=1;i
您的问题在于:

FD_ZERO(&set);
FD_SET(fd_serv, &set);
FD_SET(fd_comm, &set); 
while (1) 
{
   [...]
您只需要设置一次
fd_集
,但是
fd_集
将被
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\u ISSET()
。所有其他的东西都是毫无意义的,因为您额外的
FD_SET()
FD_CLR()
调用正在修改一个
FD_SET
,您只需在下一个while循环迭代开始时使用
FD_ZERO()
调用就可以将其清除

另外,作为旁注:
usleep(10000)
call应该消失——如果您正确地调用了
select()
,那么在
select()
之外的任意时间段睡眠既不必要也不可取。

您的问题在于:

FD_ZERO(&set);
FD_SET(fd_serv, &set);
FD_SET(fd_comm, &set); 
while (1) 
{
   [...]
您只需要设置一次
fd_集
,但是
fd_集
将被
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\u ISSET()
。所有其他的东西都是毫无意义的,因为您额外的
FD_SET()
FD_CLR()
调用正在修改一个
FD_SET
,您只需在下一个while循环迭代开始时使用
FD_ZERO()
调用就可以将其清除

另外,作为旁注:
usleep(10000)
call应该消失——如果您正确地调用了
select()
,那么在
select()
之外的任意时间段睡眠既不必要也不可取。

Read,and。很难调试我们无法编译的代码,特别是当我们无法访问一些重要的位时。很难调试我们无法编译的代码,特别是当我们无法访问一些重要的位时。