旧版
FD_ZERO(&rfds);
FD_ZERO(&master);
FD_SET(sockserver, &master);
fdmax = sockserver;
for(;;) {
rfds = master;
if( select(fdmax+1, &rfds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
新版
FD_ZERO(&rfds);
FD_ZERO(&master);
FD_SET(sockserver, &master);
fdmax = sockserver;
for(;;) {
FD_ZERO(&rfds);
for(j=0;j<max_socket;j++){
if(FD_ISSET(j,&master))
FD_SET(j,&rfds);
}
/* Not copying directly, because you can't assume that the set is integer type.
It may be anything. */
if( select(fdmax+1, &rfds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
我尝试旧版本,并且在运行到select()时会崩溃,然后我搜索新版本并尝试,它仍然崩溃。我还尝试移出所有我认为可能是堆栈溢出的局部变量,但它仍然会崩溃。
有人可以回答这个问题吗? 非常感谢。
答案 0 :(得分:2)
在这两个版本中,您没有正确设置fdmax
。如果master
中的任何套接字大于sockserver
的值,select()
将忽略它们。 select()
的第一个参数必须比rfds
中的最大套接字高+1。
此外,在旧版本中,无法保证rfds = master
是有效操作。在可能存在错误的平台上,请改用FD_COPY()
:
FD_COPY(&master, &rfds);
但在这种情况下,通过使用 new 版本,您无需使用FD_COPY()
(如果可用)。
正如Craig在评论中所述,确保max_socket
实际上有效,不超过FD_SETSIZE
等。
试试这个:
FD_ZERO(&master);
FD_SET(sockserver, &master);
...
FD_ZERO(&rfds);
fdmax = -1;
for(j = 0; (j < max_socket) && (j < FD_SETSIZE); ++j){
if (FD_ISSET(j, &master)) {
FD_SET(j, &rfds);
fdmax = j;
}
}
if (select(fdmax+1, &rfds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
...
如果您仍然遇到问题,那么您需要提供更实际的MCVE来证明问题的实际效果。