代码之家  ›  专栏  ›  技术社区  ›  Jason Rohrer

TCP套接字可能中断,使其仍在接收,但无法再发送?

  •  0
  • Jason Rohrer  · 技术社区  · 8 年前

    用插座编程已经15年了,以前从未遇到过这种情况。

    运行一个标准的TCP套接字服务器,客户机连接到它,消息通过打开的套接字来回发送。这是一个游戏服务器,客户机在服务器运行的游戏世界中工作。在过去的3个月里,这个服务器已经处理了160万个这样的套接字会话。

    服务器正在记录从客户端接收的消息。客户机正在记录从服务器接收到的消息,以及它发送到服务器的消息。

    在多次来回传递消息数分钟后,服务器从这个客户机接收到最后一条消息,然后通过那个套接字不再接收任何其他消息。另一方面,客户机一直在从服务器接收消息,并一直在向服务器发送消息(从它的角度来看,这些消息都是小消息,可能只是堆积在发送缓冲区中)。

    服务器最终检测到客户机处于空闲状态,发送了一条再见消息,并关闭了连接。客户甚至收到了告别信息。

    这个过程持续了18秒(从服务器从客户机收到最后一条消息的时间,到它发送再见消息的时间)。

    问题:对于TCP套接字,这种行为是可能的吗?它只在一个方向上断裂或停止?

    我在想应该要穿的背包。如果客户机->服务器路由断开,则服务器将无法再获得ACK。这意味着服务器将在超时后一次又一次地重新发送所有数据包。但这并不意味着它将停止发送新的数据包。客户机也不会因为发送的数据包而得到任何确认,但出于另一个原因(数据包根本无法通过,因此服务器无法对其进行确认),因此它也会超时并重新发送。

    也许这不是一个TCP问题,而是一个网络路由问题。双向路线只能单向行驶吗?

    1 回复  |  直到 8 年前
        1
  •  0
  •   Gil Hamilton    8 年前

    我认为这可能是路由问题。以上关于单向交通的其他评论仅适用于 shutdown(2) 这大概是您应该知道的,因为您的应用程序必须明确地做到这一点。

    两个方向的路线可能不同(如@ronmaupin所指出的)。或者可能只是在某个中间路由器的某个方向上存在大量拥塞。任何一种情况都可能导致数据包丢失。

    面对这样丢掉的数据包,由于没有接收到ACK(我认为您已经正确地描述了),双方将继续重试他们的传输。初始重传时间基于每个端点机器计算的近似往返时间。随后的重传有一个指数退避——例如,请参见 http://www.pcvr.nl/tcpip/tcp_time.htm#21_2 为了解释。结果是最终超时。

    考虑到指数退避和一定数量的重传(该数字是平台特定的,并且通常是可配置的),通常需要18秒以上的时间,本地网络堆栈才会宣布会话死机。但听起来您的应用程序可能用它自己的超时(对于游戏服务器来说似乎是合理的)来短路这个进程。

    我怀疑你以前从未见过,因为一般来说,两个方向的路由是相同的,当路由器“向下”时,它在两个方向都向下。

    推荐文章