gpt4 book ai didi

linux - 如果网络出现故障,套接字会发生什么

转载 作者:IT王子 更新时间:2023-10-29 00:54:02 26 4
gpt4 key购买 nike

假设一个简单的网络模型:A已经成功的创建了一个到B的TCP连接,他们之间是这样通信的

A <----------> B

我知道,如果 A 上的程序挂掉(例如核心转储),那将导致向 B 发送 RST 数据包。因此,B 的任何读取尝试都会导致 EOF,B 的任何写入尝试都会导致 SIGPIPE .我说得对吗?

但是,如果假设 A 上的网络出现故障(例如电缆/路由器故障),那么 B 的读/写尝试会发生什么情况?在我的情况下,所有套接字都已设置为非阻塞。这样一来,我是不是无法检测到网络错误?

顺便说一下,我注意到有一个选项 SO_KEEPALIVE在套接字中可能对我有用http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/ .但是我想知道如果我将探测间隔设置为2~3秒(默认为75秒),成本会是多少?而且似乎间隔配置是全局配置,所以这会影响机器上的所有套接字吗?

最后一个问题...假设网络已经崩溃,任何写入尝试都会在一段时间后导致 EPIPE。但是,如果我不尝试写入,而是将此套接字放入 epoll 设备,那么会发生什么? epoll_wait 会返回 EPOLLHUP 或 EPOLLERR 事件吗?

最佳答案

还有许多其他方式可以使 TCP 连接在未被发现的情况下失效

  • someone yanks out a network cable inbetween.
  • the computer at the other end gets nuked.
  • a nat gateway inbetween silently drops the connection
  • the OS at the other end crashes hard.
  • the FIN packets gets lost.
  • undetectable errors: A router in-between the endpoints may drops packets.(including control packets)reff

在所有情况下,当您尝试在套接字上写入时,您都可以通过程序中的 SIGPIPE 错误了解它并终止它。

通过read()无法得知对方是否存活。 Thants 为什么 SO_KEEPALIVE 有用。 Keepalive 是非侵入性的,在大多数情况下,如果您有疑问,您可以将其打开,而不必担心做错什么。但请记住,它会产生额外的网络流量,这会对路由器和防火墙产生影响。

这也会影响你机器上的所有套接字!(你是对的)。并且因为 SO_KEEPALIVE 会增加流量并消耗 CPU。最好设置 SIGPIPE 句柄,如果应用程序有可能写入断开的连接。

Also use SO_KEEPALIVE at reasonable place in the application. It's poor to use it for whole connection duration (i.e do use so_keepalive when server works for long on client query).

Setting the probing interval Dependends on your application or sayApplication layer protocol.

尽管启用 TCP keepalive,您最终还是会检测到它 - 至少在几个小时内。

如果网络出现故障,但不是尝试写入,而是将套接字放入某个 epoll 设备:

epoll 中的第二个参数:

 n = epoll_wait (efd, events, MAXEVENTS, -1);

设置正确的事件相关代码,好的做法是检查此代码
注意事项如下。

n = epoll_wait (efd, events, MAXEVENTS, -1);  
for (i = 0; i < n; i++)
{
if ((events[i].events & EPOLLERR) ||
(events[i].events & EPOLLHUP) ||
(!(events[i].events & EPOLLIN)))
{
/* An error has occured on this fd, or the socket is not
ready for reading (why were we notified then?) */
fprintf (stderr, "epoll error\n");
close (events[i].data.fd);
continue;
}

else if (sfd == events[i].data.fd)
{
/* We have a notification on the listening socket, which
means one or more incoming connections. */

// Do what you wants
}
}

EPOLLRDHUP 的意思是:
Stream socket peer 关闭连接,或关闭写入一半的连接。 (此标志对于编写简单代码以在使用边缘触发监视时检测对等关闭特别有用。)

关于linux - 如果网络出现故障,套接字会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12811653/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com