在 ssh 守护进程中,select() 总是正确返回,但执行以下 nmap 脚本后,
nmap -sV -O -A --script ssh2-enum-algos
select() 始终返回 1,即使没有与 ssh 服务器建立连接。
还有其他几个类似的线程,但我找不到我的代码的问题。
我的代码看起来像这样,
while (1)
{
memcpy(tmp_read_set, read_set, sizeof(fd_set));
retValSS = select(FD_SETSIZE, tmp_read_set, NULL, NULL, NULL);
switch (retValSS)
{
case -1:
LOG1(CRIT, "select() failed, errno=%d", ipcom_errno);
goto cleanup;
case 0: // Timeout....
break;
default:
for(i=0; i<MAX_LISTEN_PORTS; i++)
{
if(lst_sock[i] == INVALID_SOCKET)
break;
if(FD_ISSET(lst_sock[i], tmp_read_set))
{
clt_sock = accept(lst_sock[i], NULL, NULL);
if (INVALID_SOCKET == clt_sock) /*INVALID_SOCKET is -1*/
{
LOG1(ERR, "accept() failed, errno=%d", errno);
continue;
}
if(srv_ctx->no_clients >= srv_ctx->max_clients)
{
LOG0(INFO, "max no of connected clients reached, disconnecting client");
close(clt_sock);
continue;
}
else
{
//some work is being done
}
}
}
}
}
我不断收到以下错误日志,
accept() 失败,errno = 0
奇怪的是,errno 为 0,表示没有错误。如果没有错误,我认为accept()应该不会失败。 有人可以解释一下accept()在什么情况下会失败吗?
如果有人能提供帮助,我将非常感激。
您期望 select() 返回什么?考虑一下 select() 通常用于等待多个文件描述符 - 如果您要连接两个文件描述符,您如何纯粹根据 select 的返回值知道哪个文件描述符成功/失败?显然你不会。
这就是为什么 select() 只是告诉您哪些文件描述符以某种方式发生了更改,并且您应该独立确定那是什么。对于 connect(),您应该调用 getsockopt() 来检索连接尝试的结果。请参阅这个答案,其中解释了如何执行非阻塞 connect()。