【问题标题】:non blocking socket select returns 1 after connect非阻塞套接字选择在连接后返回 1
【发布时间】:2011-12-07 15:26:27
【问题描述】:

首先我想说这是另一个问题:Similar but not the same

我的代码如下所示:

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 地址存在,但没有服务器正在侦听我尝试连接的端口)。

选择总是返回 1。为什么?根据 man 它应该超时并返回 0。 在此之后,当我尝试向套接字写入内容时,它返回 -1/ECONNREFUSED。

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

【问题讨论】:

标签: c linux sockets nonblocking select-function


【解决方案1】:

我不知道您在手册页的哪个位置看到它应该超时。

如果没有防火墙丢弃数据包,连接将很快被拒绝(来自主机的一个数据包,一个数据包回复)。因此,一旦收到重置,连接套接字上的“事件”就会出现。这将唤醒select,并带有(至少)一个活动套接字。

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

【讨论】:

  • 这个问题的好答案。
【解决方案2】:

这是correct behavior,因为挂起的错误会导致套接字变得可读和可写。与任何其他系统调用一样,您需要明确检查错误情况。您可以将套接字包含在异常 fdset(select() 的第四个参数)中,然后直接获取通知,或者您可以稍后检查 a number of ways 中的错误。

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

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多