C# 停止侦听套接字的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/452327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Proper way to stop listening on a Socket
提问by Anton
I have a server that listens for a connection on a socket:
我有一个侦听套接字连接的服务器:
public class Server
{
private Socket _serverSocket;
public Server()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 1234));
_serverSocket.Listen(1);
}
public void Start()
{
_serverSocket.BeginAccept(HandleAsyncConnectionMethod, null);
}
public void Stop()
{
//????? MAGIC ?????
}
//... rest of code here
}
What is the correct (clean) way to close down the socket?
关闭套接字的正确(干净)方法是什么?
Is it sufficient to call:
是否足以调用:
_serverSocket.Disconnect(true);
in the Stop() method? or is there other work that needs to happen to close the connection cleanly?
在 Stop() 方法中?或者是否需要进行其他工作才能干净地关闭连接?
采纳答案by Wim Coenen
TCP connection termination correctly involves a four-way handshake. You want both ends to inform the other that they're shutting down and then acknowledge each other's shutdown.
TCP 连接终止正确涉及四次握手。您希望两端都通知对方他们正在关闭,然后确认对方已关闭。
Wikipedia explains the process: http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination
维基百科解释了这个过程:http: //en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination
This post explains how to make it happen in C#: http://vadmyst.blogspot.com/2008/04/proper-way-to-close-tcp-socket.html
这篇文章解释了如何在 C# 中实现它:http: //vadmyst.blogspot.com/2008/04/proper-way-to-close-tcp-socket.html
回答by alexwood
That shouldhandle it...but if you need to make absolutely sure, you could always kill it with fire:
那应该可以处理它......但是如果你需要绝对确定,你总是可以用火杀死它:
Not for sockets, but same idea applies., which is to close it in every way possible, then finally set the socket to null.
不适用于套接字,但同样的想法也适用。,也就是用各种可能的方式关闭它,然后最后将socket设置为null。
回答by Wim Coenen
Since you are listening for incoming TCP connections, you could use System.Net.Sockets.TcpListenerwhich does have a Stop() method. It does not have asynchronous operations though.
由于您正在侦听传入的 TCP 连接,因此您可以使用System.Net.Sockets.TcpListener,它确实具有 Stop() 方法。虽然它没有异步操作。
回答by scottm
You should use Socket.Shutdown()and then Socket.Close(). Socket.Disconnect() is usually only used if you intend on reconnecting the same socket.
您应该使用Socket.Shutdown()然后使用Socket.Close()。Socket.Disconnect() 通常仅在您打算重新连接同一个套接字时使用。
回答by Spencer Ruport
First, you need to make sure you're keeping track of any client sockets that were created in the process of BeginAccept. Shut those down first using the Socket.Shutdown() and Socket.Close() methods. Once those have all been shut down then do the same on the listening socket itself.
首先,您需要确保跟踪在 BeginAccept 过程中创建的任何客户端套接字。首先使用 Socket.Shutdown() 和 Socket.Close() 方法关闭它们。一旦这些都被关闭,那么在监听套接字本身上做同样的事情。
回答by Konstantin Salavatov
2 ways to close it properly without exceptions
无一例外地正确关闭它的2种方法
1) create temporary connecting socket and connect it to listening one so it could have its handler triggered then just finish it with normal EndAccept and after that close both.
1)创建临时连接套接字并将其连接到侦听套接字,以便它可以触发其处理程序,然后用普通的 EndAccept 完成它,然后关闭两者。
2) just Close(0) listening socket which will result in false shot to its callback, if you then look into your listening socket you will see that its state is "closed" and "disposed". This is why calling EndAccept would cause exception. You may just ignore it and do not call EndAccept. Listening socket will go down immediately without timeout.
2)仅关闭(0)侦听套接字,这将导致对其回调的错误射击,如果您随后查看侦听套接字,您将看到其状态为“关闭”和“已处置”。这就是调用 EndAccept 会导致异常的原因。您可以忽略它而不调用 EndAccept。侦听套接字将立即关闭而不会超时。
回答by charfeddine.ahmed
The cleanest way to have Accept call break immediately is to call _serverSocket.Dispose(); Any other call to methods in the like of Shutdown or Disconnect will throw an exception.
立即中断 Accept 调用的最简洁方法是调用 _serverSocket.Dispose(); 对 Shutdown 或 Disconnect 等方法的任何其他调用都将引发异常。