关于so​​cket select()崩溃

时间:2015-07-07 02:18:22

标签: c sockets embedded-linux

旧版

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()时会崩溃,然后我搜索新版本并尝试,它仍然崩溃。我还尝试移出所有我认为可能是堆栈溢出的局部变量,但它仍然会崩溃。

有人可以回答这个问题吗? 非常感谢。

1 个答案:

答案 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来证明问题的实际效果。