【问题标题】:Read socket after closing read side?关闭读取端后读取套接字?
【发布时间】:2015-07-30 17:59:20
【问题描述】:

我是服务器。我正在从套接字读取数据。我从套接字中读到了一些不好的东西,这让我想断开连接,但我不想丢失“已经在管道中”的传入数据。我需要告诉发件人停止发送,因为我即将断开连接,当我关闭套接字时,他放在线上的任何东西都会丢失。

我该怎么办?我要发出shutdown(socket, SHUT_RD) 吗?如果我这样做了,这会告诉发件人停止发送但允许我继续读取套接字直到所有数据都耗尽吗?


应用程序应该永远不会丢失数据。

服务器是用 Java 编写的,我不是开发人员。我正在向他提出建议,以便我发送给他的数据永远不会丢失。我正在开发无法很好地控制套接字 API 的客户端(Node.js)。

我不得不手动编写 HTTP 管道,因为 Node.js 不这样做。这就是客户端只是在连接上继续发送 HTTP 并且在发送下一个请求之前不等待响应的地方。客户端发送大约 30k QPS。

我有一个方案,我将请求排入 FIFO 队列,然后在响应返回时将其删除。如果连接断开,我将重播任何尚未确认的请求,但这最终也会播放“The Bad”请求,并且连接会一次又一次地断开。

我似乎记得读过一些以:

开头的东西

那些试图重写 TCP 的人注定要失败……

所以我想我会放弃我复杂的系统,看看 TCP 是否能满足我的需求。都是Linux环境。

Java 开发人员在他的应用程序前面使用 Nginx,而 Nginx 是在不关闭连接的情况下断开连接,只是硬关闭连接。

无论如何,重点是,为了让我的客户端具有容错能力,无论另一端做什么,我都希望负责将数据丢失降至最低。保留未确认的请求队列并在必要时重播它们会起作用,但它并不像看起来那么简单(请注意我没有预料到的“重播错误事务”问题作为示例,它还会导致双重数据,其中情况还可以,但一般情况下可能不行)。

服务器终止连接还有其他原因。它不时这样做是为了让客户端进行 DNS 查找(他们可能想即时更改服务器的 IP 地址),或者可能只是出现网络故障导致连接中断。

【问题讨论】:

  • 你用什么语言运行这个?您想保留哪些数据?你在使用异步套接字吗?
  • @A.Abramov 语言或 aysnc 有什么不同?
  • @EJP 语言,所以我会知道如何给他举例。异步不仅是一种不同的语法,而且是一个完全不同的概念 - 您可能能够在关闭异步连接时从当前读取中读取数据,这可能很重要。
  • 您的服务器能否向客户端发送错误响应,以便客户端知道哪个请求是“错误请求”,从而知道不再发送它?
  • 为什么要发送不良交易?这才是真正的问题。两端都不需要容错编码错误。

标签: sockets shutdown


【解决方案1】:

我是服务器。我正在从套接字读取数据。我从套接字中读到了一些不好的东西,让我想断开连接,但我不想丢失“已经在管道中”的传入数据。

为什么不呢?你读到“坏事”:是什么让你认为事后有好事?或者您可以正确地重新同步到它?在跳过一些未知数量的坏字节以到达下一条消息的开头之后?

我需要告诉发件人停止发送,因为我即将断开连接,当我关闭套接字时,他放在线上的任何东西都会丢失。我要发出shutdown(socket, SHUT_RD) 吗?如果我这样做,这会告诉发件人停止发送吗

这是高度依赖于平台的,取决于服务器平台:

  • Windows 将发出 RST,最终为发件人提供“连接重置”。
  • 基于 BSD 的 Unix 将接受并忽略数据(即 ACK 它但将其丢弃,而不是将其输入到您的套接字接收缓冲区中),因此发送者将继续发送尽可能多的数据,直到您关闭套接字,当他将读取流的结尾或在写入时获得“连接重置”时。
  • Linux 将接受数据,直到您的套接字发送缓冲区填满;然后您的接收窗口将关闭,这会阻止发件人;然后当您关闭套接字时,发送方将获得“连接重置”。

还允许我继续读取套接字,直到所有数据都耗尽?

它可能会或可能不会让您读取所有已经到达的数据。例如,Windows 在关机后立即为您提供SocketException: Socket input is shutdown。您不应收到任何在您发出关闭指令时正在传输的数据。

奇怪的要求。我会直接断开连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多