C - select()返回1,即使绑定到给定端口的远程主机上的进程被杀死



我编写了一个程序,使用非阻塞connect()select()组合来检查到远程主机a的连接特定端口。select()也有一些超时值,在我的情况下是2.5s。我正在测试该程序连接到在远程主机上运行SMTP服务的进程绑定到25号端口。如果我杀死在远程主机上运行的进程,那么select()也会返回1来告诉该进程正在写(套接字添加到写入fd_set)是可能的。这背后的原因是什么,以及在这种情况下是否可以使用select()。我尝试使用connect(),当这种连接不可能时立即返回,但在连接需要超时的情况下不起作用,这就是为什么我使用select()

select()并没有告诉你读写是可能的,它只是告诉你它不会阻塞(或者如果套接字处于非阻塞模式则返回错误EWOULDBLOCK)。只要本地套接字缓冲区未满,套接字始终是可写的。此外,如果在远程进程死亡后发送了任何东西,您将收到一个RST包,并且在此之后尝试写将立即返回ECONNRESET。因此,当这种情况发生时,套接字将被标记为可写。

我能够通过在select()函数调用之后使用另一个connect()来完成。张贴代码片段

error = connect(soc, (struct sockaddr *)serveraddr, sizeof(struct sockaddr)) ;
 if(error == 0){
        DIAGC("vsrserv", 1, "Returning while connect is 0");
        return 0;
}
if(errno != EINPROGRESS)
        return -1;

int retVal = select (soc+1, &writeFD, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)(&timeout));
if (retVal == 0){
        close(soc);
        return -1;
}
socklen_t len = 0;
int m = getsockopt(soc, SOL_SOCKET, SO_ERROR, &error, &len) ;
if(m < 0){
        close(soc);
        return -1;
}
//connect() returns immediately if it is able to connect to that particular port
//Since select() returned 1 it means host was reachable so just need to verify the port on the remote host which we can do with another with connect() call
error = connect(soc, (struct sockaddr *)serveraddr, sizeof(struct sockaddr)) ;
    if(error < 0){
        close(soc);
        return -1;
}

最新更新