本帖最后由 lidanger 于 2014-01-21 08:29:57 编辑

解决方案 »

  1.   


    private void StartAccept(SocketAsyncEventArgs acceptEventArg)
            {
                if (!m_bRunning)
                {
                    return;
                }            if (acceptEventArg == null)
                {
                    acceptEventArg = new SocketAsyncEventArgs();
                    AsyncState state = new AsyncState();
                    state.Sock = m_sListen;
                    state.Async = true;
                    acceptEventArg.UserToken = state;
                    acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(EventCompleted);
                }
                else
                {
                    acceptEventArg.AcceptSocket = null;
                }            // 查询等待是否有空闲socket资源
                m_semaMaxOnline.WaitOne();            lock (m_SocketPool)
                {
                    try
                    {
                        acceptEventArg.AcceptSocket = m_SocketPool.Pop();
                    }
                    catch { }
                }            if (acceptEventArg.AcceptSocket == null)
                {
                    return;
                }            try
                {
                    AsyncState state = (AsyncState)acceptEventArg.UserToken;
                    state.Async = m_sListen.AcceptAsync(acceptEventArg);
                    if (!state.Async)
                    {
                        AcceptHandler(acceptEventArg);
                    }
                }
                catch
                {
                    lock (m_SocketPool)
                    {
                        m_SocketPool.Push(acceptEventArg.AcceptSocket);
                    }
                    StartAccept(acceptEventArg);
                }
            }private void EventCompleted(object sender, SocketAsyncEventArgs e)
            {
                if (e == null)
                {
                    return;
                }            switch (e.LastOperation)
                {
                    case SocketAsyncOperation.Accept:
                        AcceptHandler(e);
                        break;
                    case SocketAsyncOperation.Receive:
                        ReceiveHandler(e);
                        break;
                    case SocketAsyncOperation.Send:
                        SendHandler(e);
                        break;
                    default:
                        m_strErrMsg = String.Format("非accept、receive或send的操作:{0}", e.LastOperation);
                        break;
                }
            }private void AcceptHandler(SocketAsyncEventArgs e)
            {
                SocketAsyncEventArgs readEventArgs = null;
                lock (m_rwEventArgsPool)
                {
                    readEventArgs = m_rwEventArgsPool.Pop();
                }            if (readEventArgs == null)
                {
                    e.AcceptSocket.Shutdown(SocketShutdown.Both);
                    lock (m_SocketPool)
                    {
                        m_SocketPool.Push(e.AcceptSocket);
                    }                StartAccept(e);                return;
                }
                
                readEventArgs.AcceptSocket = e.AcceptSocket;            if (e.AcceptSocket != null)
                {
                    Client client = m_ClientPool.Pop();
                    client.Sock = e.AcceptSocket;
                    client.EventArgs = readEventArgs;
                    client.HeartBeat = DateTime.Now;
                    client.Sock = e.AcceptSocket;
                    lock (m_dicSockClient)
                    {
                        if (m_dicSockClient.ContainsKey(client.Sock))
                        {
                            m_dicSockClient.Remove(client.Sock);
                        }
                        m_dicSockClient.Add(client.Sock, client);
                    }
                }            if (m_bufferPool.SetBuffer(readEventArgs))
                {
                    AsyncState state = (AsyncState)readEventArgs.UserToken;
                    try
                    {
                        state.Async = readEventArgs.AcceptSocket.ReceiveAsync(readEventArgs);
                        if (!state.Async)
                        {
                            ReceiveHandler(readEventArgs);
                        }
                    }
                    catch
                    {
                        CloseClient(readEventArgs);
                    }
                }            StartAccept(e);
            }
      

  2.   

    感觉有时候用C#还不如C++,很多东西封装得你完全不知道里面是什么。。出了问题只能改思路。。
    不行的话只好把整个accept改成全循环了。。
      

  3.   

    最简单的方法,加一个ManualResetEvent,
    在循环开始的时候 reset,  
    在complete或者收到连接后Set,
    在AcceptAsync之后 WaitOne.
      

  4.   

    哎,你写了一大堆代码,看起来实在是太乱。Accept之后,Send之前,都需要创建新的 SocketAsyncEventArgs 实例。如果你这个时候还纠结于“共用”对象,那么你就做不到并发处理了!只有Reveive以及(客户端的)Connect可以共用 SocketAsyncEventArgs 对象,因为针对同一个客户端必须“顺序”读取字节流(但是你不需要等待处理完毕才开始下一次Receive)。
      

  5.   

    你的 m_semaMaxOnline,这看起来是搞乱的根源。程序中不要随便阻塞,不要随便写 WaitOne 代码。至少在这里根本不用 WaitOne。msdn上关于tcp通讯的文章里的代码基本上都有问题的,不需要用 ManualResetEvent 它用了这个,造成代码冗长。纠结于“阻塞”的代码在逻辑上不如纯粹的并发代码更清晰,因为他们的设计思路就不一样。如果你压根就不写 ManualResetEvent /WaitOne ,你一定会另外思考程序流程,那样得到的代码又少、又清晰。
      

  6.   


    你的“阻塞”式代码,本来就是一个“披着多线程外衣、实际上偷运的是循环思路”的代码。你始终没有搞明白多线程异步代码应该如何写。而且msdn上的类似代码也是误导了你,它也是同样问题。当接收到Accept之后,必须创建一个新的 SocketAsyncEventArgs 实例用来维持与当前客户端的一系列持续的 Reveive操作。一旦创建这个之后,就再次异步等待当前 SocketAsyncEventArgs  实例的下一个 Accept 操作。总共只有(大致)两条代码,却让你写成了几十条代码这么巨大的一个程序。
      

  7.   

    socket通信,网上完整例子很多,搜一个参考一下,不要自己靠拍脑袋想,靠这里抄一句那里抄一句的拼凑