Socket.Close并不真的关闭tcp socket吗? (c#)
看来,使用socket.Close()为一个TCP套接字,并没有完全关闭套接字。在下面的示例中,我试图连接到端口9999处的example.com,该端口未打开,并在短暂超时后尝试关闭套接字。Socket.Close并不真的关闭tcp socket吗? (c#)
for (int i = 0; i < 200; i++)
{
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.LingerState = new LingerOption(false, 0);
sock.BeginConnect("www.example.com", 9999, OnSocketConnected, sock);
System.Threading.Thread.Sleep(50);
sock.Close();
}
但是当我看看netstat的循环完成后,我发现有很多半开的插座:
TCP israel-xp:6506 www.example.com:9999 SYN_SENT
TCP israel-xp:6507 www.example.com:9999 SYN_SENT
TCP israel-xp:6508 www.example.com:9999 SYN_SENT
TCP israel-xp:6509 www.example.com:9999 SYN_SENT
编辑 。好吧,一些情况下丢失。我正在使用beginconnect,因为我期望套接字连接失败(9999未打开),并且在我的真实代码中,一旦定时器被设置,我就调用socket.Close()。 On OnSocketConnected我调用了EndConnect,它引发一个异常(试图调用一个处理对象的方法)。 我的目标是在套接字连接阶段有一个短暂的超时。
任何线索我在做什么错? 谢谢!
它将关闭套接字的.NET部分。然而,根据TCP规范,操作系统必须保持套接字的较低级别信息点打开一段时间以检测重传等。在这种特殊情况下,为了检测对发送的SYN数据包的回复,可能需要稍微保持一段时间,以便它可以更明智地回复,而不会与发送的其他数据包混淆在一起。
你打电话给*Begin*Connect
- 这样做是异步的。你甚至可能试图在连接之前关闭套接字 - 所以当它连接时,它仍然是开放的。
尝试同步连接 - 或关闭OnSocketConnected
,以便看到关闭真正连接的套接字的效果。
看我的编辑。 我正在使用BeginConnect,并且在调用Close之前,我的实际代码会等待超时。只需在这样一个套接字上调用EndConnect(其中dest端口未打开),只需要很长时间即可完成。 或者换句话说,我要超时套接字连接阶段之后X毫秒(而不是高得离谱数毫秒窗口在默认情况下)。 – r0u1i 2010-01-06 18:14:30
按照设计,您应该在关闭套接字之前始终调用Shutdown
。
mySocket.Shutdown(SocketShutdown.Both);
mySocket.Close();
所以切实做好禁止发送和接收在插座上,这样就不会被接受输入的数据你已经关闭了它之后,即使操作系统仍然有控制权。
Jon Skeet也有一个观点,即你打开连接异步,它可能实际上是连接,而你试图关闭它。但是,如果您打电话给Shutdown
,它将不会允许您收到信息,因为您正在经历。
编辑:只能Shutdown
已经连接的插座,这样你写你的代码牢记这一点。
+1对Jon Skeet的回答发表评论。 :-) – 2010-01-06 18:15:30
如果套接字尚未连接,则ShutDown会引发一种不安 - 这正是我的场景。 – r0u1i 2010-01-06 18:16:48
然后你应该使用OnSocketConnected来调用它的ShutDown并关闭它,或者这样的性质。 – 2010-01-06 18:40:09
您初始化在每个循环新的Socket ...带* .close()关闭旧的,并在开始您创建一个新的具有相同的参数和以前的Socket。
是的。但我看到更多的开放式套接字不止一个。 – r0u1i 2010-01-06 18:15:58
这是有道理的,但不是徘徊于虚假应该解决吗? – r0u1i 2010-01-06 18:22:29
哦,逗留不这样做。所以,没有办法让Windows终止套接字。 – r0u1i 2010-01-07 13:33:21
默认情况下,它将在Windows真正关闭之前处于FIN_WAIT状态4分钟。更有意思的是,如果你重新打开另一个连接到相同的目的地/端口窗口将重用FIN_WAIT中匹配的连接。 – Jay 2010-08-25 19:35:48