C#异步网络IO和OutOfMemoryException

3
我正在使用C#开发客户端/服务器应用程序,需要使异步套接字工作,以便可以同时处理多个连接。技术上讲,它现在的工作方式是正确的,但是大约运行3分钟后会出现OutOfMemoryException异常。MSDN建议在socket.BeginAccept()之后使用WaitOne()来使用WaitHandler,但实际上我无法这样做。当我尝试在代码中执行此操作时,它说WaitHandler是一个抽象类或接口,我不能实例化它。我想也许我可以尝试静态引用,但它没有WaitOne()方法,只有WaitAll()WaitAny()方法。主要问题是文档中没有提供完整的代码片段,因此您无法看到他们的“等待处理程序”来自哪里。它只是一个名为allDone的变量,在片段中还具有Reset()方法,而WaitHandler没有。

在查找了文档后,我发现了一些关于Threading命名空间中的AutoResetEvent相关的内容。它有一个WaitOne()Reset()方法。所以我尝试将其用于while(true) { ... socket.BeginAccept( ... ); ... }。不幸的是,这样只能一次处理一个连接。所以我真的不知道该怎么办了。以下是我的代码:

 class ServerRunner
    {
        private Byte[] data = new Byte[2048];
        private int size = 2048;
        private Socket server;
        static AutoResetEvent allDone = new AutoResetEvent(false);

        public ServerRunner()
        {
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint iep = new IPEndPoint(IPAddress.Any, 33333);
            server.Bind(iep);
            Console.WriteLine("Server initialized..");
        }

        public void Run()
        {

            server.Listen(100);
            Console.WriteLine("Listening...");
            while (true)
            {
                //allDone.Reset();
                server.BeginAccept(new AsyncCallback(AcceptCon), server);
                //allDone.WaitOne();
            }
        }

        void AcceptCon(IAsyncResult iar)
        {
            Socket oldserver = (Socket)iar.AsyncState;
            Socket client = oldserver.EndAccept(iar);
            Console.WriteLine(client.RemoteEndPoint.ToString() + " connected");
            byte[] message = Encoding.ASCII.GetBytes("Welcome");
            client.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(SendData), client);
        }

        void SendData(IAsyncResult iar)
        {
            Socket client = (Socket)iar.AsyncState;
            int sent = client.EndSend(iar);
            client.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveData), client);
        }

        void ReceiveData(IAsyncResult iar)
        {
            Socket client = (Socket)iar.AsyncState;
            int recv = client.EndReceive(iar);
            if (recv == 0)
            {
                client.Close();
                server.BeginAccept(new AsyncCallback(AcceptCon), server);
                return;
            }
            string receivedData = Encoding.ASCII.GetString(data, 0, recv);
            //process received data here
            byte[] message2 = Encoding.ASCII.GetBytes("reply");
            client.BeginSend(message2, 0, message2.Length, SocketFlags.None, new AsyncCallback(SendData), client);
        }
    }
网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接