简体   繁体   English

为什么此套接字/文件描述符分配无效?

[英]Why is this socket/ file descriptor assignment invalid?

I'm trying to write a simple server in c that plays a two player game. 我正在尝试用c编写一个简单的服务器,该服务器可以玩两个玩家的游戏。 It checks for incoming connections, and if there is no player1, it saves player1's file descriptor (to be used later for sending and receiving) and if there is no player2, it does the same. 它检查传入的连接,如果没有player1,它将保存player1的文件描述符(以后将用于发送和接收),如果没有player2,它将执行相同的操作。 I have this loop set up that I modified from Here . 我已经从Here修改了这个循环。 My problem is that I want to receive from one, and send to the other, but it seems that my assignments are invalid. 我的问题是我想从一个接收并发送到另一个,但是我的分配似乎无效。 When I try to send to player2, it fails or it sends garbage. 当我尝试发送到player2时,它失败或发送垃圾。 Sometimes, sending to player1 sends back to the server(?). 有时,发送给player1将发送回服务器(?)。 Am I using select correctly and looping through the file descriptor set correctly? 我是否正确使用select并正确遍历设置的文件描述符? Any feedback would be appreciated. 对于任何反馈,我们都表示感谢。

// 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
                }
            }
        }
    }
}

The toobusy part should use newfd, not fdmax. toobusy部分应该使用newfd,而不是fdmax。 Otherwise there's no easy spotted error in this code. 否则,此代码中不会出现容易发现的错误。

Your comment "Sometimes, sending to player1 sends back to the server(?)" makes me think that player1_fd and player2_fd might be uninitialized or perhaps initialized to 0 instead of -1. 您的注释“有时,发送给player1发送回服务器(?)”使我认为player1_fd和player2_fd可能未初始化,或者可能初始化为0而不是-1。 You should double check that you set them to -1 before the loop. 您应该仔细检查是否在循环之前将它们设置为-1。

A few additionally notes: 一些其他注意事项:

  • Are you sure master is 0 initialized? 您确定master已初始化为0吗? Have you called FD_ZERO on it? 您打过FD_ZERO了吗?
  • You should use FD_COPY to copy master to read_fds. 您应该使用FD_COPY将母版复制到read_fds。

Finally, I'd recommend to use a library for event handling, such as libevent or libev. 最后,我建议使用一个库来处理事件,例如libevent或libev。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM