我有一个阻塞套接字(至少它在以下代码中出现):
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
ERROR("%s: error opening socket", __func__);
return (RESP_ERROR);
}
t.tv_sec = timeout;
t.tv_usec = 0;
int rf = fcntl(sock, F_GETFD);
ERROR("fcntl ret=%d, ret & O_NONBLOCK = %d", rf, rf & O_NONBLOCK);
if ((setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof (t)) < 0)
|| (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&t, sizeof (t)))) {
strerror_r(errno, err, 254);
ERROR("%s: error on setsockopt -> %s", __func__, err);
close(sock);
return (RESP_ERROR);
}
rf = fcntl(sock, F_GETFD);
ERROR("after select fcntl ret=%d, ret & O_NONBLOCK = %d", rf, rf & O_NONBLOCK);
if (connect(sock, (struct sockaddr *)&dst, sizeof (dst)) != 0) {
strerror_r(errno, err, 254);
ERROR("%s: error on connect -> %s", __func__, err);
close(sock);
return (RESP_ERROR);
}
这是来自日志:
3月6日10:42:04 tcpclient:fcntl ret = 0,ret&amp; O_NONBLOCK = 0
3月6日10:42:04 tcpclient:选择fcntl ret = 0后,ret&amp; O_NONBLOCK = 0
3月6日10:42:14 tcpclient:authenticate:连接时出错 - &gt;正在进行中的操作
看来这是一个阻塞套接字但是返回非阻塞的典型错误? Linux是2.6.18-308.el5。有什么想法吗?
答案 0 :(得分:5)
如果timeout
不是0
,则connect()
的呼叫会超时并返回。这种情况与连接是否建立无关。
从超时到期的那一刻起,connect()
的行为就像在非阻塞套接字上调用一样。
参考此案例(从man connect
逐字逐句忽略“立即”):
EINPROGRESS
套接字是非阻塞的,无法立即完成连接。通过选择用于写入的套接字,可以选择(2)或轮询(2)以完成。 select(2)表示可写性后,使用 getsockopt(2)读取SOL_SOCKET级别的SO_ERROR选项以确定connect()是否成功完成(SO_ERROR为零)或失败(SO_ERROR是此处列出的常见错误代码之一,解释 - 失败的原因)。
man 7 socket
个州(我用斜体字):
SO_RCVTIMEO和SO_SNDTIMEO
指定接收或发送超时,直到报告错误为止。 [...]如果没有传输数据并且已达到超时,则返回-1,并将errno设置为EAGAIN或EWOULDBLOCK ,就像套接字是 指定为非阻塞。 [...]超时仅对执行套接字I / O的系统调用有效(例如,read(2),recvmsg(2),send(2), SENDMSG(2));超时对select(2),poll(2),epoll_wait(2)等没有影响。
没有关于connect()
的消息,所以我不确定我的答案是否成立。
答案 1 :(得分:1)
尝试'if((connect(...))&lt; 0)'。你可能根本没有收到任何错误。