【发布时间】:2021-08-19 00:25:54
【问题描述】:
我正在使用非阻塞套接字连接到服务器。
在特定的测试场景中,服务器宕机,这意味着一个 TCP SYN 出去了,但是没有响应,永远无法建立连接。
在此设置中,select 通常会在 2 秒后超时,返回 0。
这是大多数时候的行为,而且看起来是正确的。
但是,在大约 5% 的情况下,select 立即返回 1(表示套接字在掩码中是可读的)。
但是当我从套接字read(2) 时,-1 会返回 'Network is unreachable'
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// sockfd checked and > 0
// set non-blocking
struct timeval tv{};
tv.tv_sec = 2;
int ret = connect(sockfd, addr, addrlen ); // addr set elsewhere
if (ret < 0 && errno == EINPROGRESS)
{
fd_set cset;
FD_ZERO(&cset);
FD_SET(sockfd, &cset);
ret = select(sockfd + 1, &cset, nullptr, nullptr, &tv);
// returns 1 sometimes
}
在第一篇文章中,我错误地表示在错误情况下,网络上只有一个 TCP SYN(没有重试)。
这不是真的;在错误和非错误情况下,网络上都有一个 TCP SYN 在 1 秒后重新发送。
什么可能导致这种情况,有没有办法获得与select 一致的行为?
【问题讨论】:
-
它设置为非阻塞,但我没有将它包含在代码中(虽然有评论)
-
Similar here(也链接在上面的链接中)
-
@ryyker 这个问题是相关的,但情况不同。显然返回了 TCP RST,这使得套接字可读.. 就我而言,网络没有响应
-
您是否考虑过
selecting 用于写作 而不是阅读?这有什么改变吗?
标签: c linux sockets nonblocking