TCP套接字能注意到网络中断的异常吗?
Can a TCP socket notice the exception of network broken?
我在linux上通过套接字与服务器建立了tcp链接。我使用select()函数来监视是否有数据,如果有,我使用recv来获取数据。
现在我想知道网络是否坏了(比如电缆被拔掉了)但是,即使我监视异常,我也无法得到异常。
FD_SET( m_socket, &except_fds );
int result = select( m_socket + 1, &fds, 0, &except_fds, timeout == -1 ? 0 : &tv );
让我困惑的是android上有类似的实现(java.net.socket),如果我将手机设置为飞行模式,我可以立即捕获异常。
select()实现平台是特定的吗?
总之,这种方法是否可以用来监控网络的破碎?如果没有,有什么解决办法吗?
TCP协议的一般工作方式,一个错误是这样的数据传输失败(不是ACK
'd)。除非数据传输失败,否则没有错误。
因此,您可以定期发送小数据包来检测使用setsockopt
SO_KEEPALIVE
的断开连接,或者定义一个简单的心跳协议。您也可以使用TCP_KEEPCNT
, TCP_KEEPIDLE
和TCP_KEEPINTVL
覆盖keepalive默认值
让我困惑的是android上有类似的实现(
java.net.Socket
),如果我将手机设置为飞行模式,我可以立即捕获异常。
不太相似。java.net.Socket
不使用select()
,除非在不支持SO_RCVTIMEO
的平台上读取超时。
当然。
select()
实现平台是否特定?
号总之,这种方法是否可以用来监控网络的破碎?
如果没有,有什么解决办法吗?
唯一可以可靠地检测到TCP连接断开的方法是尝试写入它。最终,在考虑缓冲和重试之后,write()
或send()
和朋友将返回-1与errno == ECONNRESET
。
您不需要做什么特别的事情。TCP连接的丢失,无论是由于另一端关闭它还是由于错误,都不是例外。您已经在等待套接字可读,如果连接关闭或出现错误,您的等待就结束了。当等待结束时,您的代码应该已经尝试从套接字读取,因此它应该已经检测到这种情况。
请注意,在大多数平台上,暂时失去连接不会关闭TCP连接。在临时连接丢失的情况下,这将是非常恼人的。事实上,在过去,有些系统具有长时间的TCP连接,但只有在有活动时才具有网络连接。即使故意禁用网络连接,这些连接仍保持活动状态。这个行为是设计好的。
检测TCP链路是否仍然可用的最可靠方法是在其上发送数据。如果链路的另一端无法确认数据,则发送最终将超时。(对send函数的调用可能已经返回成功,但超时将触发一个错误,使套接字可读。
如果你想检测网络条件的变化,你将需要使用特定的系统服务。
在较低的级别,您可以在udev中使用规则检测网络设备的热插拔或移除。更高一些的是像NetworkManager这样的服务,它将通过DBUS进行通信。您可以订阅它以获得网络更改的通知。
如果你没有使用NetworkManager,那么它取决于你的系统脚本。有些有ifdown-post和ifdown-local。其他一些脚本可以运行以响应DHCP事件,其中包括网络拔掉。其他一些程序可以运行来监视网络插头状态,如ifplug或ifplugd或netplugd。
如果你想让内核直接通知你,而不是使用系统服务或守护进程,我认为你需要使用netlink协议来扫描可用的网络设备。
您可能需要将套接字设置为使用keep alive,以便它能够检测连接是否已断开。您需要使用setsocketopt()
和SO_KEEPALIVE
作为第三个参数。
如果select
正在监视的任何文件描述符报告错误,则select
将返回。
对于套接字,如果操作系统与本地链路层网络失去连接,将报告错误。这意味着如果主机完全失去网络连接,select
将返回。当你拔掉网线或手机切换到飞行模式时,就会发生这种情况。
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 在发布模式下使用 VS2017 在C++发布模式下构建的应用不会在未经处理的异常时中断
- C 调试中断异常
- 在C++的功能性ISA模拟器上实现陷阱(异常/中断)
- 将 INT3 中断保留给视觉工作室上的应用程序异常处理程序
- 在std::for_each的执行过程中累积结果,该异常被中断
- 编程语言捕获和处理的异常是否算作软件中断
- 异常不会中断指令流
- lldb-在抛出C++异常之前中断
- 捕获中断/异常
- TCP套接字能注意到网络中断的异常吗?
- 在GDB中抛出特定异常类型时如何中断
- 如何为代码块禁用特定win32异常类型的VC++中断