c - 为什么这个套接字/文件描述符分配无效?

标签 c sockets select file-descriptor

我正在尝试用 c 语言编写一个简单的服务器来玩两人游戏。它检查传入连接,如果没有player1,它会保存player1的文件描述符(稍后用于发送和接收),如果没有player2,它会执行相同的操作。我设置了这个循环,我是从 Here 修改的。我的问题是我想从一个接收,然后发送给另一个,但我的分配似乎无效。当我尝试发送给玩家 2 时,它失败或发送垃圾。有时,发送到player1会发送回服务器(?)。我是否正确使用了 select 并正确循环了文件描述符集?如有任何反馈,我们将不胜感激。

// add the listener to the master set
FD_SET(listener, &master);

// keep track of the biggest file descriptor
fdmax = listener; // so far, it's this one

// main loop
while (1) {
    read_fds = master; // copy it
    if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
         error("select");
    }

    // run through the existing connections looking for data to read
    for(i = 0; i <= fdmax; i++) {

        //This indicates that someone is trying to do something
        if (FD_ISSET(i, &read_fds)) {
            if (i == listener) {

                addrlen = sizeof remoteaddr;
                newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen);

                if (newfd == -1) {
                    error("accept");
                } else {
                    FD_SET(newfd, &master);
                    if (newfd > fdmax) {
                        fdmax = newfd;
                    }

                    /* If we have the maximum number of players, we tell if that it's busy */
                    if (players >= 2) {
                         toobusy(fdmax); close(fdmax); FD_CLR(fdmax, &master);
                    }  else {                                                        
                         //Problem here?
                         if (player1_fd == -1) {
                               player1_fd = newfd;                                  
                         }

                         if ((player1_fd != -1) && (player2_fd == -1)) {
                               player2_fd = newfd;                                   
                         }

                         players++;
                         if (players == 2) {
                               sendhandles(); //says two players exist
                         }
                    }
                }
            } else {
                //Possible problems here
                if (i == player1_fd || i == player2_fd) {
                     receive(i); //Processes the messages
                }
            }
        }
    }
}

最佳答案

toobusy 部分应该使用 newfd,而不是 fdmax。否则这段代码中不会有容易发现的错误。

您的评论“有时,发送到player1会发送回服务器(?)”让我认为player1_fd和player2_fd可能未初始化,或者可能初始化为0而不是-1。您应该在循环之前仔细检查是否将它们设置为 -1。

一些补充说明:

  • 您确定 master 已初始化为 0 吗?您调用过 FD_ZERO 吗?
  • 您应该使用 FD_COPY 将 master 复制到 read_fds。

最后,我建议使用事件处理库,例如 libevent 或 libev。

关于c - 为什么这个套接字/文件描述符分配无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9762218/

相关文章:

c - 从 strtok 向其传递字符串数组后,execvp 返回错误 "No such file or directory"

java.net.SocketException : No buffer space available (maximum connections reached? ): 连接

mysql - SQL如何合并选择并排除一个?

c - 即使在向数组中添加更多具有值的元素后,数组的大小仍保持不变

C 语言中的 Ctrl+Z 信号处理

c - 在两个不同进程之间共享 OpenSSL BIO

ios - 有没有办法找到套接字对等进程的pid?

mysql - 连接 SQL 列中的选择

php - 向 Laravel 中的选择查询添加一个具有值的新列

c - 发生概率函数