我想知道是否有一种方法可以避免在关闭 Netty 中的连接时设置 TCP RST 标志而不是 TCP FIN 标志,因为在 TCP 接收缓冲区中剩余输入数据。
用例是:
- 客户端(用 C 编写)发送包含许多字段的数据包。
- 服务器读取数据包,在早期字段遇到错误,抛出异常。
- 异常处理程序捕获异常,写入错误消息,并将写入时关闭回调添加到写入未来。
问题是:
接收缓冲区中的剩余数据会导致 Linux(或 Java..)使用 RST 标志标记 TCP 数据包。这可以防止客户端读取数据,因为当它开始尝试时,它发现由于套接字关闭而导致读取错误。
使用直接的 Java 套接字,我相信解决方案是在关闭之前调用 socket.shutdownOutput() 。Netty 中是否有等效功能或解决方法?
如果我只是继续从套接字读取,避免 RST 可能是不够的,因为在调用 close 时缓冲区中可能有也可能没有数据。
供参考:http ://cs.baylor.edu/~donahoo/practical/CSockets/TCPRST.pdf
更新:
问题的另一个参考和描述:http: //docs.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html
调用 shutdownOutput() 应该有助于更有序地关闭连接(通过发送 FIN),但如果客户端仍在发送数据,那么无论如何都会发送 RST 消息(请参阅 EJP 的回答。可能会提供等效的 shutdownOutput()在 Netty 4+。
解决方案是从客户端读取所有数据(但您永远无法确定客户端何时会完全停止发送,尤其是在恶意客户端的情况下),或者在发送响应后关闭连接之前简单地等待(参见答案来自声名狼藉)。