当前位置: 首页 > 知识库问答 >
问题:

有没有一种方法可以检测到TCP套接字已被远程对等端关闭,而不从它读取?

季华茂
2023-03-14

首先,介绍一下解释其动机的背景:我正在研究一个非常简单的基于select()的TCP“镜像代理”,它允许两个防火墙客户端间接地相互对话。两个客户端都连接到此服务器,并且一旦两个客户端连接,客户端A发送到服务器的任何TCP字节都会转发到客户端B,反之亦然。

这或多或少起作用,但有一个小问题:如果客户机A连接到服务器并在客户机B连接之前开始发送数据,服务器就没有地方放数据了。我不想将其缓冲在RAM中,因为这样会最终使用大量RAM;我也不想丢弃这些数据,因为客户机B可能需要这些数据。因此,我选择第三个选项,即在客户机B也连接之前,不在客户机A的套接字上选择()-for-read-ready。这样客户机A就会阻塞,直到一切准备就绪。

共有1个答案

慎兴业
2023-03-14

如果要检查套接字是否实际关闭而不是数据,可以在recv()上添加msg_peek标志,以查看数据是否到达,或者您是否得到0或错误。

/* handle readable on A */
if (B_is_not_connected) {
    char c;
    ssize_t x = recv(A_sock, &c, 1, MSG_PEEK);
    if (x > 0) {
        /* ...have data, leave it in socket buffer until B connects */
    } else if (x == 0) {
        /* ...handle FIN from A */
    } else {
        /* ...handle errors */
    }
}

即使A在发送一些数据后关闭,您的代理也可能希望在将FIN转发给B之前先将该数据转发给B,因此在读取了A发送的所有数据之后更早地知道A在连接上发送了FIN是没有意义的。

TCP连接在双方发送FIN之后才被视为关闭。但是,如果A已强制关闭其endpoint,则在尝试对其发送数据并接收epipe(假设已取消sigpipe)之后,您才会知道这一点。

在多读了一点您的镜像代理应用程序之后,由于这是一个防火墙遍历应用程序,似乎您实际上需要一个小的控制协议来允许您验证这些对等体实际上是允许彼此对话的。如果您有一个控制协议,那么您有许多解决方案可供您使用,但我主张的一个是将其中一个连接描述为服务器,而将另一个连接描述为客户端。然后,您可以重置客户端的连接,如果没有服务器存在以获取它的连接。您可以让服务器等待客户端连接直到某个超时。服务器不应该启动任何数据,如果它在没有连接的客户端的情况下启动数据,您可以重置服务器连接。这消除了为死连接缓冲数据的问题。

 类似资料:
  • 问题内容: 如果地理位置下降,我需要JavaScript显示手动输入。 我尝试过的 两者均未描述用户以前是否拒绝访问地理位置。 问题答案: 和两个接受时出现错误时被调用的第二回调。错误回调为错误对象提供了一个参数。对于拒绝的权限,将为(数值)。 例: 编辑:正如@Ian Devlin指出的那样,Firefox(本文发布时为4.0.1)似乎不支持此行为。它将按预期在Chrome和 可能 Safari

  • 我正在尝试编写一个服务器,它将监听一个端口,接受一个传入的客户端连接,然后将该客户端连接放入堆栈中,以等待将来的消息到达。理想情况下,当消息到达时,我希望触发一个事件,然后允许服务器执行一个操作。

  • 问题内容: 我有一个过程密集型任务,我想在后台运行。 用户单击一个页面,PHP脚本运行,最后,根据某些条件(如果需要),它必须运行Shell脚本EG: 当前,我使用shell_exec, 但这 需要脚本等待输出。有什么方法可以执行我想要的命令, 而无需 等待命令完成? 问题答案: 如何添加。 请注意,这也摆脱了stdio和stderr。

  • 问题内容: 在此问题中找到了我能找到的最接近的示例:https : //github.com/tensorflow/tensorflow/issues/899 使用此最小的可复制代码: 但是,返回的FLOPS始终为“无”。有没有一种方法可以具体测量FLOPS,尤其是PB文件? 问题答案: 有点晚了,但也许将来对某些访客有帮助。对于您的示例,我成功测试了以下代码段: 也可以将分析器与以下代码段结合使

  • 问题内容: 我正在自动执行一个调用CAPTCHA来验证登录名的网页,但是我注意到该页面仅在使用自动化测试代码时才请求此CAPTCHA,而当我手动执行时则不请求。我要求开发人员团队在质量检查环境中禁用它,但是通过安全代码是不可能的。 我需要知道是否有一种方法可以不对浏览器说我正在此页面上使用自动测试。 你能帮我吗? 问题答案: 不 ,没有任何方法可以隐瞒您正在运行自动化测试。 WebDriver界面