连接后,非阻塞套接字select返回1

首先我想说的是,这是另外一个问题: 相似但不一样

我的代码如下所示:

struct addrinfo hints, *res; struct sockaddr* serveraddr; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; int res2 = getaddrinfo(ip, port, &hints, &res); printf("getaddrinfo() res: %d, %d\n", res2, errno); serveraddr = res->ai_addr; //create new socket int soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); printf("socket() res: %d, %d\n", socket, errno); //set nonblocking mode unsigned long on = 1; res2 = ioctl(soc, FIONBIO, &on); printf("ioctl() res: %d\n, %d", res2, errno); res2 = connect(soc, serveraddr, sizeof(struct sockaddr)); printf("connect() res: %d, %d\n", res2, errno); //check if socket is ready fd_set wfds; FD_ZERO(&wfds); FD_SET(soc, &wfds); struct timeval t; t.tv_sec=15; t.tv_usec=0; res2 = select(soc + 1, 0, &wfds, 0, &t); printf("select() res: %d, %d\n", res2, errno);` 

我正在连接到存在的机器(IP地址存在,但没有服务器侦听端口,我试图连接)。

select总是返回1.为什么? 根据男人,它应该超时,并返回0.此后,当我尝试写入套接字它返回-1 / ECONNREFUSED。

这是预期的行为? 如果是,如何检查select()后我们是否连接?

我不知道你在哪里看到应该超时。

如果没有防火墙丢弃数据包,则连接将被相当快地拒绝(从主机发送一个数据包,一个数据包应答)。 因此,一旦接收到复位,连接插座上的“事件”就会进入。 这将唤醒select (至少)一个活动套接字。

读取或写入该套接字的第一次尝试将返回基础连接错误。

这是正确的行为 ,因为挂起的错误会导致套接字成为可读写的。 与其他任何系统调用一样,您需要明确检查错误条件。 您可以将套接字包含在异常fdset(select()的第四个参数)中,并直接获取通知,或者可以稍后以多种方式检查错误。

小心写入套接字,因为SIGPIPE可能发生。 一般来说,您应该设置一个SIGPIPE处理程序并与EPIPE同步处理错误。