繁体   English   中英

.NET TcpSocket编程

[英].NET TcpSocket programming

在.NET的多连接环境中接受套接字的正确方法是什么? 即使负载很高,以下条件是否足够?

while (true)
{
   //block untill socket accepted
   var socket = tcpListener.AcceptSocket();
   DoStuff(socket) //e.g. spawn thread and read data
}

也就是说,我可以在单个线程中接受套接字,然后在线程/数据流/任何形式中处理套接字。 所以问题只是关于接受部分。

您可能需要BeginAccept异步操作,而不是同步Accept。

而且,如果您想处理负载,则绝对不希望每个连接都有线程-同样,您可以使用异步方法。

看一下Reactor还是Proactor模式,这取决于您是否要阻止。 我会推荐《 并发和联网对象模式》一书

这样做应该可以,但是如果负载更高,则可以考虑使用此方法的异步版本: BeginAcceptSocket / EndAcceptSocket

如果您想要性能最高的服务器,那么BeginAcceptSocket是一个更好的选择。

更重要的是,这些异步操作在后台使用了线程 ,而在当前的实现中,您正在创建和销毁许多线程,这确实很昂贵。

我认为最好的方法是调用BeginAccept(),然后在OnAccept内再次调用BeginAccept。这应该为您提供最佳的并发性。

OnAccept应该是这样的:

private void OnAccept(IAsyncResult ar)
{
   bool beginAcceptCalled = false;
   try
   {
       //start the listener again
       _listener.BeginAcceptSocket(OnAccept, null);
       beginAcceptCalled = true;
       Socket socket = _listener.EndAcceptSocket(ar);
       //do something with the socket..
   }
   catch (Exception ex)
   {
       if (!beginAcceptCalled)
       {
          //try listening to connections again
          _listener.BeginAcceptSocket(OnAccept, null);
        }
    }
}

在性能方面,这并不重要。 重要的是您如何与每个客户沟通。 这种处理将比接受套接字消耗更多的CPU。

我会将BeginAccept / EndAccept用于侦听器套接字 BeginReceive / EndReceive用于客户端套接字。

由于我使用的是异步CTP和数据流,因此当前代码如下所示:

private async void WaitForSockets()
{
    var socket = await tcpListener.AcceptSocketAsync();
    WaitForSockets();
    incomingSockets.Post(socket);
}

注意,看起来像递归调用不会导致堆栈溢出或阻塞。 它将只是为新的套接字启动一个新的等待者并退出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM