c - select() 无效参数

标签 c sockets

我有一个包含 6 个套接字的数组,每个套接字都设计用于监听传入消息。在每个套接字上,我需要调用 select() 来监听传入的消息。这段代码可以编译,但是当我运行它时,我收到一条消息

选择失败:参数无效

错误号:22

谁能看出我做错了什么?谢谢!

这段代码在 int main() 中:

int listenfd[6];
fd_set read_set;
struct timeval tv;
time_t start_time;

make_connections(listenfd, neighbor, servAddr, read_set);

FD_ZERO(&read_set);

// add the accepted connections to the read set for use with select()
for (i=0; i<6; i++) {
    FD_SET(listenfd[i], &read_set);
}

tv.tv_sec = 5;                  // seconds
tv.tv_usec = 5000000;    // microseconds

gettimeofday(&tv, NULL);
start_time = tv.tv_sec;

// EDIT: made the following change per suggestion by ThePelaton
//        same error exists, though
//if ( (select(6, &read_set, NULL, NULL, &tv)) == -1) {

int max = listenfd[0];
for (i=1; i<6; i++) {
    if (listenfd[i] > listenfd[i-1]) {
        max = i;
    }
}

if ( (select(listenfd[max]+1, &read_set, NULL, NULL, &tv)) == -1) {
       perror("select failure");
       fprintf(stdout, "errno: %d\n", errno);
       exit(EXIT_FAILURE);
}

我的其他功能:

void make_connections(int listenfd[6], Neighbor neighbor[6], struct sockaddr_in servAddr, fd_set read_set) {

    int num_hosts = 6;
    int i, rc, on=1;
    struct sockaddr_storage their_addr;
    socklen_t addr_size;

    for (i=0; i<6; i++) {        
        // Create one socket for each neighbor
        if((listenfd[i] = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            exit(1);
        }

        /*************************************************************/
        /* Allow socket descriptor to be reuseable                   */
        /*************************************************************/
        rc = setsockopt(listenfd[i], SOL_SOCKET,  SO_REUSEADDR,
                        (char *)&on, sizeof(on));
        if (rc < 0)
        {
            perror("setsockopt() failed");
            close(listenfd[i]);
            exit(-1);
        }

        /*************************************************************/
        /* Set socket to be non-blocking.  All of the sockets for    */
        /* the incoming connections will also be non-blocking since  */
        /* they will inherit that state from the listening socket.   */
        /*************************************************************/
        rc = ioctl(listenfd[i], FIONBIO, (char *)&on);
        if (rc < 0)
        {
            perror("ioctl() failed");
            close(listenfd[i]);
            exit(-1);
        }

        /* get server IP address (input must be IP address, not DNS name) */
        bzero(&servAddr,sizeof(servAddr));                          //zero the struct
        servAddr.sin_family = AF_INET;                              //address family (ipv4)
        servAddr.sin_port = htons(neighbor.port);  //sets port to network byte order
        servAddr.sin_addr.s_addr = INADDR_ANY;

        // first attempt to bind / listen on each port
        if (bind(listenfd[i], (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
            perror("bind failed");
            exit (-1);
        }

        if (listen(listenfd[i], 10) < 0) {
            perror("listen() failed");
            exit (-1);
        }

    }
}

编辑 2:很确定我已经弄明白了。我正在使用我的时间值 (tv) 为我的过程做一些时间戳记。看起来这是无效参数的来源,而不是套接字。

最佳答案

在调用 select 时使用 listenfd[] + 1 中的最大值,而不是硬编码值 6,其他文件描述符,如 stdin 等,占用前几个槽。

关于c - select() 无效参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19895861/

相关文章:

c - 具有链接到同一功能的多个设备属性的 Linux 驱动程序

c - OpenMP任务的任务调度点

c++ - C 到 C++ : Transitioning from one language to the other

C、读取文本文件

c# - cocoaasynsocket到C Sharp服务器

C 创建原始 UDP 数据包

c# - 设置套接字的本地端点

c# - 通过套接字发送数据不完整

c - 在 c 中未初始化时 int 的默认值。为什么我得到不同的输出?

c - 软终止一个简单的网络服务器