我正在尝试用c编写一个简单的服务器,该服务器可以玩两个玩家的游戏。它检查传入的连接,如果没有player1,它将保存player1的文件描述符(以后将用于发送和接收),如果没有player2,它也会这样做。我设置了从Here修改的此循环。我的问题是我想从一个接收并发送到另一个,但是我的分配似乎无效。当我尝试发送到player2时,它失败或发送垃圾。有时,发送到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将母版复制到read_fds。
最后,我建议使用一个库来处理事件,例如libevent或libev。
关于c - 为什么此套接字/文件描述符分配无效?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9762218/