2

我对 Async 方法实现了什么有点困惑。我在查找如何使服务器接受多个连接时遇到了它。在查找 Aync 在 C# 中的确切作用时,让我感到困惑的是,据我所知,它不是它自己的线程。但是,它还允许您避免锁定和停滞。例如,如果我有以下内容:

    ConnectionManager()
    {
        listener = new TcpListener(port);
        listener.BeginAcceptSocket(new AsyncCallback(acceptConnection), listener);
    }

    public void acceptConnection(IAsyncResult ar)
    {
        //Do stuff
    }

这是否意味着一旦找到连接,它就会执行“acceptConnection”函数,然后继续通过调用者函数执行?(在这种情况下超出范围)。这如何让我创建一个能够接受多个客户端的服务器应用程序?尽管我之前使用过线程来管理服务器/客户端交互,但我对这个概念还是很陌生。如果我有点模糊,请告诉我。我在 MSDN 上查找了多个示例,但仍然有些困惑。提前谢谢你!

4

2 回答 2

3

一旦找到连接,它就会执行“acceptConnection”函数

是的

然后通过调用者函数继续执行?

不。

异步方法实现了什么

如果做得好,它允许使用更少的资源处理更高数量的请求/秒。

想象一下,您正在创建一个应该接受 10 个 TCP 端口上的连接的服务器。

使用阻塞 API,您必须创建 10 个线程来接受套接字。线程是昂贵的系统资源,例如每个线程都有自己的堆栈,线程之间的切换需要相当长的时间。如果客户端连接到某个套接字,操作系统将不得不唤醒相应的线程。

使用异步 API,您可以发布 10 个异步请求。当客户端连接时,您的 acceptConnection 方法将由 CLR 线程池中的线程调用。

还有一件事情。

如果你想在等待异步 I/O 操作完成后继续执行调用函数,你应该考虑新的 C# 的 async/await 语法,它允许你这样做。该功能可作为 Visual Studio 2010 的独立库“Async CTP”使用,并包含在 Visual Studio 2012 中。

于 2012-11-09T00:43:33.463 回答
2

我不自称是 ac# 或套接字专家,但据我了解,您上面的代码将接受第一个连接,然后不再接受。您需要建立另一个 BeginAccept。

就像是:

TcpListener listener = null;

ConnectionManager()
{
    listener = new TcpListener(port);
    listener.BeginAcceptSocket(new AsyncCallback(acceptConnection), listener);
}

public void acceptConnection(IAsyncResult ar)
{
    // Create async receive data code..

    // Get ready for a new connection
    listener.BeginAcceptSocket(new AsyncCallback(acceptConnection), listener);

}

因此,除了异步连接之外,通过使用异步接收数据,接受连接会很快完成并设置侦听新连接。我想你也可以重新订购这个。

对于直接套接字连接(不是 TcpListener),这是我使用的:

(connectedClient 是我自己的类,它处理接收和传输功能并保存有关连接的其他信息)。

int Port = 7777; // or whatever port you want to listen on
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port);
listenSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

listenSocket.Bind(ipLocal);

// create the call back for any client connections...
        listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);

private void OnClientConnection(IAsyncResult asyn)
    {
        if (socketClosed)
        {
            return;
        }

        try
        {
            Socket clientSocket = listenSocket.EndAccept(asyn);

            ConnectedClient connectedClient = new ConnectedClient(clientSocket, this);

            connectedClient.MessageReceived += OnMessageReceived;
            connectedClient.Disconnected += OnDisconnection;
            connectedClient.MessageSent += OnMessageSent;

            connectedClient.StartListening();

            // create the call back for any client connections...
            listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null);

        }
        catch (ObjectDisposedException excpt)
        {
            // Deal with this, your code goes here

        }
        catch (Exception excpt)
        {
            // Deal with this, your code goes here
        }

    }

我希望这已经回答了你在找什么?

于 2012-11-09T00:26:37.757 回答