来自 AsyncState 和 EndAccept() 函数的 .NET 套接字之间的区别
Posted
技术标签:
【中文标题】来自 AsyncState 和 EndAccept() 函数的 .NET 套接字之间的区别【英文标题】:Difference between .NET Sockets from the AsyncState and the EndAccept() function 【发布时间】:2012-08-17 21:17:42 【问题描述】:在阅读这个Async Sockets example 时,我发现了这段代码:
// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);
我很难找到关于这两个套接字之间区别的文档,我还想知道关闭处理程序或关闭处理程序将如何影响原始套接字。谁能解释一下,或者给我一些文档?
【问题讨论】:
【参考方案1】:套接字是特定机器上的唯一连接,即127.0.0.1:1024
。一次只能建立一个活动连接。 “侦听器”侦听固定端口(例如我上面示例中的 1024)。它的工作是成为接受连接的“公共”方式。一旦它接受一个连接,它就会在一个新的、随机的(嗯,相当伪随机的)选择端口上创建一个新的套接字。然后原始连接应用程序和主机可以通过该套接字进行通信,从而释放侦听套接字以获取另一个连接(这将为新连接分配另一个端口号,等等)。
EndAccept
通常是您建立连接后需要做的所有事情。 listener
通常会继续侦听以接受更多连接。如果没有,您通常只需处置或关闭套接字以停止侦听并取消任何待处理的接受。 handler
用于执行应用程序需要的任何通信,完全独立于listener
套接字。当您使用完 handler
套接字后,您将处理或关闭它,因为 listener
是独立的,它会继续“运行”。
Shutdown
将刷新面向连接的套接字(在Close
之前调用)上的所有待处理数据,并且不会影响任何其他套接字。
【讨论】:
【参考方案2】:监听器是监听连接的套接字。您不想让侦听器被占用,否则多个客户端将无法通过该套接字进行连接。在该套接字上调用 EndAccept 会为您提供一个套接字供服务器与客户端通信,并打开侦听器以进行更多连接。
关闭处理程序不应影响侦听器套接字。
【讨论】:
感谢您的信息。在处理程序上调用 ShutDown() 怎么样?有什么见解吗?也许我根本不需要调用它——这很好,Socket 接口是一个大杂烩,只有在某些使用上下文中才有意义。所以,我的想法是我不需要关闭处理程序。 您可能应该在完成处理程序套接字后关闭它,或者该端口将保持打开状态直到您的进程退出。关闭处理程序套接字不会影响侦听器套接字,因此您仍然可以获得传入连接。您的套接字是否存在特定问题?【参考方案3】:任何基于套接字的 .NET 服务器应用程序都将涉及至少两种套接字:
-
用于侦听入站连接(同步或异步)的侦听器套接字
通过调用侦听器套接字的 Accept() 方法返回的客户端套接字。
你说的例子是异步监听,socket首先调用BeginAccept()方法,参数是异步方法的地址。现在,如果您不调用相应的 EndAccept() 方法,则原始侦听器套接字将被阻塞,并且来自客户端的任何进一步连接都可能丢失。
Socket.ShutDown(Both) 方法用于优雅地关闭带有连接的套接字,而 Socket.Disconnect(True) 将强制执行相同的操作。无论如何, Socket.Close() 应该遵循这些方法。有关更多信息,请参阅此 SO 链接:c#/.Net Socket.Shutdown
【讨论】:
以上是关于来自 AsyncState 和 EndAccept() 函数的 .NET 套接字之间的区别的主要内容,如果未能解决你的问题,请参考以下文章