关闭读取端后读取套接字?

时间:2015-05-19 04:10:02

标签: sockets shutdown

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

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

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

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

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

我有一个方案,我在FIFO队列中排队请求,然后在响应回来时删除它们。如果连接断开,我会重播任何未被确认的请求但是这最终也会播放“Bad”请求并且连接再次被丢弃,并且又一次又一次地被丢弃。

我似乎记得读过以下内容开头的内容:

  

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

所以我想我会废弃我复杂的系统,看看TCP是否可以提供我需要的东西。这都是Linux环境。

Java开发人员正在使用Nginx面向他的应用程序,而Nginx就是在没有关闭的情况下放弃连接,只是难以关闭连接。

无论如何,重点是,为了使我的客户端容错,我想负责最小化数据丢失,无论另一端是什么。保留一个未经处理的请求队列并在必要时重放它们会起作用,但它并不像看起来那么简单(注意“重放不良事务”问题,我没有预料到这个问题,它也会导致双重数据,情况还可以,但一般情况下可能没有。)

服务器终止连接还有其他原因。它会不时地让客户端进行DNS查找(他们可能想要在运行中更改服务器的IP地址),或者可能只是存在破坏连接的网络故障。

1 个答案:

答案 0 :(得分:1)

  

我是服务员。我正在从套接字读取数据。我从套接字中读到一些不好的东西,这让我想放弃连接,但我不想丢失已经在管道中的传入数据"。

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

  

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

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

  • Windows会发出一个RST,最终会让发件人重置“#”。
  • 基于BSD的Unix会接受并忽略数据(即确认它但扔掉它,而不是将其输入你的套接字接收缓冲区),这样发送方就会继续发送尽可能多的数据,直到你关闭套接字,当他要么读取流末端或者获得连接重置'在写。
  • Linux会接受数据,直到你的套接字发送缓冲区填满为止;然后您的接收窗口将关闭,从而阻止发件人;然后,当您关闭套接字时,发件人将重置'。
  

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

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

奇怪的要求。我会放弃连接。