【发布时间】: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 语言,所以我会知道如何给他举例。异步不仅是一种不同的语法,而且是一个完全不同的概念 - 您可能能够在关闭异步连接时从当前读取中读取数据,这可能很重要。
-
您的服务器能否向客户端发送错误响应,以便客户端知道哪个请求是“错误请求”,从而知道不再发送它?
-
为什么要发送不良交易?这才是真正的问题。两端都不需要容错编码错误。