select() 即使绑定到给定端口的远程主机上的进程被终止,也返回 1

select() returning 1 even in case process on remote host bound to a given port is killed

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

select() 并没有告诉你读或写是可能的,它只是告诉你它不会阻塞(或者 return 错误 EWOULDBLOCK 如果套接字是在非阻塞模式下)。只要本地套接字缓冲区未满,套接字始终是可写的。此外,如果在远程进程死亡后发送了任何内容,您将收到一个 RST 数据包,并立即尝试写入 return 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;
}