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;
}
我编写了一个使用非阻塞 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;
}