当前位置: 首页 > 面试题库 >

在写入阻止的套接字上使用TCP Keep-Alive获取断开连接通知

龚奇逸
2023-03-14
问题内容

我使用TCP Keep-Alive选项来检测死连接。它与使用读取套接字的连接一起工作良好:

setsockopt(mysock,...) // set various keep alive options

epoll_ctl(ep,mysock,{EPOLLIN|EPOLERR|EPOLLHUP},)
epoll_wait -> (exits after several seconds when remove host disconnects cable)

Epoll等待通过套接字上的EPOLLIN | EPOLLHUP退出而没有问题。

但是,如果我尝试向套接字写很多东西,直到得到EAGAIN,然后轮询读写,则在断开电缆连接时不会出现错误:

setsockopt(mysock,...) // set various keep alive options

while(send() != EAGAIN)
   ;
epoll_ctl(ep,mysock,{EPOLLIN|EPOLLOUT|EPOLERR|EPOLLHUP},)
epoll_wait -> --- Never exits!!!! even when the cable of the remove host is disconnected!!!
  • 如何解决呢?
  • 有人看到过类似的问题吗?
  • 有什么可能的方向吗?

编辑: 附加信息

当我使用wireshark监视通信时,在第一种情况下(阅读中),我每隔几秒钟收到一次确认请求。但是在第二种情况下,我根本没有检测到它们。


问题答案:

如果在传输所有数据之前拔出网络连接,则该连接不会空闲,因此在某些实现中,保持活动计时器不会启动。(请记住,keepalive不是TCP规范的一部分,因此它的实现方式根本不一致。)通常,由于指数补偿和大量重试(tcp_retries2默认为15)的组合,它可能会占用在Keepalive计时器启动之前,传输需要30分钟才能重试超时。

解决方法(如果有)取决于您所使用的特定TCP实现。一些较新版本的Linux(2011年1月4日发布的内核版本2.6.37)实现了TCP_USER_TIMEOUT。

通常的建议是在应用程序级别实现通信超时,而不是始终使用基于TCP的keepalive。参见例如HTTP Keep-
Alive



 类似资料:
  • 问题内容: 我正在使用OpenShift和WildFly 8.2.1 final来实现新的HTML5 websocket。我使用了本教程来设置这个项目。 每当我打开MyTest.html时,这就是JavaScript记录的内容: 服务器连接,然后立即断开连接。为什么?我究竟做错了什么?有什么我想念的吗? 这是模式代码-> serverendpoint.java MyTest.html: 和pom.

  • 问题内容: 检测插座是否已掉落的最合适方法是什么?还是实际上是否发送过数据包? 我有一个库,用于通过Apple网关(在GitHub上提供)将Apple Push Notifications发送到iPhone 。客户端需要打开一个套接字并发送每个消息的二进制表示形式。但不幸的是,Apple不会返回任何确认。该连接也可以重用于发送多个消息。我正在使用简单的Java套接字连接。相关代码为: 在某些情况下

  • 问题内容: 为什么有人会喜欢阻止写而不是非阻止写?我的理解是,仅当您想确保写方法返回后,另一端获得了TCP数据包时,才希望阻止写操作,但是我什至不知道这是可能的。您将必须刷新,而刷新则必须刷新 底层操作系统的写套接字缓冲区 。那么,无阻塞套接字写是否有任何缺点?就性能而言,拥有较大的底层写套接字是否会缓冲一个不好的主意?我的理解是,底层套接字写缓冲区越小,当底层套接字缓冲区已满且isWritabl

  • 问题内容: 我想创建一个非阻塞连接。像这样: 为此,我使用了另一个线程,无限循环和Linux epoll。像这样(伪代码): 如果我先运行服务器,然后运行客户端,那么一切正常。如果我先运行客户端,请稍等一会儿,再运行服务器,然后客户端将无法连接。 我究竟做错了什么?也许可以做不同的事情? 问题答案: 您应该使用以下步骤进行异步连接: 用创建套接字 开始与 如果返回值既不是也不是,则中止并返回错误

  • 我在使用https域和https套接字io时收到此警告。 我的代码是这样的: 希望有答案来解决这个问题。我已经从其他人那里搜索过,但我申请时发现不起作用。

  • 在我的客户端/服务器应用程序中,我的客户端wiil与服务器通信有两个功能:客户端要么向服务器请求数据,要么发送数据,以便服务器保存。我对这两种方法都使用一个套接字,要使用的方法由发送的第一个字节定义。如果第一个字节是“1”,它将请求数据。如果是“2”,它将发送数据(数据字节在“2”字节之后发送)。它非常适合发送数据。但是当我请求数据时,只要我不读取客户端中的套接字流,它就可以工作。这就像如果我在发