r0u*_*u1i 11 c# sockets windows tcp
似乎使用socket.Close()作为tcp套接字,并没有完全关闭套接字.在下面的示例中,我尝试在未打开的端口9999处连接到example.com,并且在短暂超时之后,我正在尝试关闭套接字.
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();
}
Run Code Online (Sandbox Code Playgroud)
但是当我在循环完成后查看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
Run Code Online (Sandbox Code Playgroud)
编辑 .好的,缺少一些背景.我正在使用beginconnect,因为我希望套接字连接失败(9999未打开),并且在我的实际代码中,一旦设置了定时器,我就调用socket.Close().On OnSocketConnected我调用EndConnect,它抛出异常(试图调用被处置对象的方法).我的目标是为套接字连接阶段设置一个短暂的超时.
我有什么问题吗?谢谢!
Ed *_*fer 18
按照设计,你应该随时打电话 Shutdown在关闭套接字之前.
mySocket.Shutdown(SocketShutdown.Both);
mySocket.Close();
Run Code Online (Sandbox Code Playgroud)
这样做可以有效地禁用套接字上的发送和接收,因此即使操作系统仍然可以控制它,它也不会在关闭后接受传入数据.
Jon Skeet也有一个观点,即由于您是异步打开连接,因此当您尝试关闭它时,它实际上可能正在连接.但是,如果您打电话Shutdown,它将不允许您在遇到时收到信息.
编辑:您只能Shutdown使用已连接的套接字,因此在编写代码时请记住这一点.
nos*_*nos 14
它将关闭套接字的.NET部分.然而,根据TCP规范,OS必须将套接字的较低级别花絮保持打开一段时间以便检测重传,并且类似.在这种特殊情况下,为了检测对发送的SYN数据包的回复,可能会将套接字保持一段时间,这样它可以更明智地回复,而不会将回复与发送的其他数据包混淆.
Jon*_*eet 10
你正在调用*Begin*Connect- 所以异步进行.您很可能在连接之前尝试关闭套接字 - 所以当它连接时,它仍保持打开状态.
尝试同步连接 - 或关闭它,OnSocketConnected以便您可以看到关闭真正连接的插座的效果.
| 归档时间: |
|
| 查看次数: |
17676 次 |
| 最近记录: |