如何防止.NET库关闭发送RST数据包 [英] How to prevent .NET libraries from sending RST packet on close

查看:146
本文介绍了如何防止.NET库关闭发送RST数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一些测试,试图隔离库(.NET)中的某些异常行为。当我通过C ++使用Winsock API并简单地调用 closesocket()时,我看到Windows端发送FIN / ACK数据包,而远程端发送回ACK数据包。这就是我所说的优雅关闭。但是,用C#编程时,我看不到所谓的平稳关闭。

I'm doing some testing trying to isolate some odd behavior in the libraries (.NET). When I use the Winsock API through C++ and simply call, closesocket(), I see the windows side send the FIN/ACK packet and the remote side send back an ACK packet. This is what I would call a graceful close. However, when programming in C# I'm not seeing what I would call a graceful close.

在C#中,我打开了套接字,然后在关闭套接字时看到了Windows首次调用 Socket.Shutdown()时,仅发送 Only FIN数据包。但是,无论如何,当我在C#中调用 Socket.Close()时,都会发送RST数据包,并且连接将被丢弃。这使我感到困惑,因为从我在线阅读的内容来看,TCP的关闭过程应该是FIN / ACK-> ACK(实际上从双方来看,但现在我只关心我的方面);即混合中根本不应该有RST数据包。从我看过的内容来看,很显然,只有在接收方不确定连接状态并希望退出时才发送RST数据包。

In C#, I open my socket and then, when closing it, I see windows send a FIN packet Only when first calling Socket.Shutdown(). However, regardless, when I call Socket.Close() in C#, an RST packet is sent and the connection summarily dropped. This confuses me because, from what I've read on line, the TCP closing process should be FIN/ACK -> ACK (from both sides actually but for now, I'm only concerned with "my" side); i.e. there should not be an RST packet in the mix at all. From what I've read, apparently, an RST packet is only sent when the receiver is uncertain about the connection state and wants out.

为什么发送此RST数据包在.NET中计划关闭,而不是在winsock API中计划关闭?有没有办法在从.NET正常关闭期间阻止RST数据包的传输?

Why is this RST packet being sent on a planned shutdown in .NET and not at all in a planned shutdown from the winsock API? Is there a way to prevent the transmission of an RST packet during a graceful shutdown from .NET?

如果很重要,在两个代码路径中,我都会阅读所有内容调用相应的 close()方法之前,套接字上的可用数据。

In case it's important, in both code paths, I'm reading all available data on the socket before calling the respective close() method.

推荐答案

阅读 Socket.Close ,这就是我发现的内容:

Reading the .NET doc of Socket.Close, this is what I found:


对于面向连接的协议,建议您先调用
Shutdown调用Close方法。这样可以确保所有数据
在关闭之前在连接的套接字上发送和接收。如果
您需要先调用Close而不先调用Shutdown,则可以通过将
DontLinger Socket选项设置为false并指定非零时间来确保
排队等待传出数据的数据被发送。 -
间隔。然后,将关闭Close,直到发送此数据或指定的
超时到期为止。如果将DontLinger设置为false并指定
a零超时间隔,则Close会释放连接,而
会自动丢弃传出的排队数据。

For connection-oriented protocols, it is recommended that you call Shutdown before calling the Close method. This ensures that all data is sent and received on the connected socket before it is closed. If you need to call Close without first calling Shutdown, you can ensure that data queued for outgoing transmission will be sent by setting the DontLinger Socket option to false and specifying a non-zero time-out interval. Close will then block until this data is sent or until the specified time-out expires. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.

这实际上是有道理的。如果缓冲区中仍然有数据(操作系统之一),并且您断开了连接或终止了该进程,则连接将被重置(TCP规范中的更多详细信息)。

which actually makes sense. If there's still data in the buffer (OS one) and you tear the connection down or kill the process the connection will be reset (more detailed information in the TCP specs).

关于发送RST的时间,请查看 TCP指南

As to when RST is sent check out TCP Guide.

我的猜测是,仍存在一些未设置的数据,正在传输的数据或在触发RST的传出/传入缓冲区中。

My guess is that there is still some unset or in transit data or in outgoing/incomming buffers that triggers the RST.

这篇关于如何防止.NET库关闭发送RST数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆