Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 我们可以在收到应用程序级确认后重置TCP连接吗?_Sockets_Networking_Tcp - Fatal编程技术网

Sockets 我们可以在收到应用程序级确认后重置TCP连接吗?

Sockets 我们可以在收到应用程序级确认后重置TCP连接吗?,sockets,networking,tcp,Sockets,Networking,Tcp,我正在研究重置TCP连接以解决TIME\u WAIT问题 让我们以以下请求-应答协议为例: 客户端打开与服务器的连接 客户端发送一个请求 服务器回复 服务器关闭 客户也关闭了 这会导致服务器出现TIME\u WAIT状态。作为一种变体,客户机可以先关闭。然后,TIME\u WAIT降落到客户机上 我们是否可以用以下内容代替步骤4和5 客户端将重置 服务器将重置以响应传入的重置 这似乎是一种避免等待时间问题的方法。服务器已通过发送回复来证明它已接收并处理了请求。一旦客户得到回复,连接就可以被消耗

我正在研究重置TCP连接以解决
TIME\u WAIT
问题


让我们以以下请求-应答协议为例:

  • 客户端打开与服务器的连接
  • 客户端发送一个请求
  • 服务器回复
  • 服务器关闭
  • 客户也关闭了
  • 这会导致服务器出现
    TIME\u WAIT
    状态。作为一种变体,客户机可以先关闭。然后,
    TIME\u WAIT
    降落到客户机上

    我们是否可以用以下内容代替步骤4和5

  • 客户端将重置
  • 服务器将重置以响应传入的重置
  • 这似乎是一种避免等待时间问题的方法。服务器已通过发送回复来证明它已接收并处理了请求。一旦客户得到回复,连接就可以被消耗掉,并且可以消失


    这是个好主意吗?

    唯一的问题是服务器不知道客户端是否收到了所有信息。这种情况是不明确的:客户端连接重置是因为客户端收到了整个回复,还是因为其他原因重置了

    添加应用程序级确认并不能可靠地解决问题。如果客户端确认,然后立即中止关闭,则客户端无法确保服务器收到该确认,因为中止关闭会丢弃未传输的数据。此外,即使发送数据,由于连接不可靠,数据也可能丢失;一旦连接中止,TCP堆栈将不再提供该数据的重新传输

    常规的、非中止的情况通过让客户机和服务器TCP堆栈独立于应用程序执行来处理最终的仪式来解决问题

    总之,如果我们只关心客户端收到它的回复,而服务器不关心是否成功,那么中止是可以的:在许多情况下这不是一个不合理的假设

    我怀疑您在服务器上等待的时间是错误的。

    如果对单个基于TCP的客户端-服务器事务遵循以下顺序,则等待时间在客户端:

  • 客户端启动到服务器的活动连接

  • 客户端向服务器发送请求

  • 客户端一半关闭连接(即发送FIN)

  • 服务器读取客户端请求直到EOF(FIN段)

  • 服务器发送回复并关闭(生成FIN)

  • 客户端读取对EOF的响应

  • 客户端关闭

  • 因为客户端是第一个发送FIN的,所以它进入了等待时间

    诀窍在于,客户端必须首先关闭发送方向,服务器通过读取整个请求在其上进行同步。换句话说,您使用流边界作为消息边界

    您试图做的是在应用程序协议内部执行请求帧,而不使用TCP帧。也就是说,服务器在客户端未关闭的情况下识别客户端消息的结尾,同样地,客户端解析服务器响应而不关心直到结尾的读取


    即使你的协议是这样的,你仍然可以进行半封闭式舞蹈动作。在检索客户端请求后,服务器仍然可以继续从其套接字读取并丢弃字节,直到读取所有内容为止,即使不需要字节。

    我想说:不,这不是一个好主意。每一种可能的解决方案最终都会产生相同的“问题”,即
    TIME\u WAIT
    最终解决的问题:甲方在确认连接结束(或确认对方最终确认连接结束)后,如何知道乙方得到了确认?答案总是:它永远无法确定这一点

    你说:

    服务器已通过发送回复来证明它已接收并处理了请求

    。。。但如果这个答复丢失了呢?服务器现在已经清理了其会话端,但客户端将永远等待该回复


    乍一看,TCP状态机可能过于复杂,但这样做是有充分理由的。

    客户机将在收到回复后重置。如果回复从未到达,则正常的连接中断机制开始发挥作用。您仍然会导致一方发送了最后一条消息(无论是重置、回复、确认还是其他),并且永远无法确定另一方是否确实收到了最后一条消息。这就是时间等待的意义所在。我们无法确保收到消息,也无法确定在所有情况下都发生了什么(参见两位将军的问题)。我认为所有这些都是正确的,并且对我们有所帮助。如果服务器对确保收到回复不感兴趣(因为它无法对故障做出反应,请参阅HTTP),那么您是否更喜欢重置解决方案?如果您不关心客户端是否收到回复,请使用UDP(假设回复不太大),我需要大消息和流控制。不过,谢谢你的建议。