写了一个异步socket的服务程序,现在如何做并发数量的测试?
我在本机上同时启动了200个客户端,运行正常,但是超过300就开始有连接不上的情况发生,我的机器2.8CPU 1G内存.
同时在两台机器上各运行200个客户端,还是各有一部分的连接不上的情况.
请问,我的服务程序的并发数量就只能是300以下了吗?
并发数量跟什么有关系,如何做测试呢?请有经验的高手指点一下.

解决方案 »

  1.   

    异步socket的服务程序对客户端的承受能力应该不止这二三百个,我们做的类似的socket服务接收的客户连接数目都远大与这个数目. 服务器的性能和你做程序的手法有很大关系,如果写的不好,很可能客户数目多的时候就不行了. 比如: 如果为每一个客户连接都单独生成一个线程,那么有二三百个客户连接后服务器就离死不远了. 或者虽然是异步接受了客户端的工作请求,但工作请求需要访问共享资源,有大量时间异步的线程处于等lock的状态,这样一来性能也会很差.
      

  2.   

    代码就是MSDN上的例子.1:没有涉及资源共享问题.
    2:每个接收线程只接收一个字符串,sleep(10000)后,然后发回客户端.
    3:用的只是异步函数,没有自行管理线程,应该是由异步线程池统一管理的.我换到server2003上再试试,可能跟XP的线程数量限制有关系?希望大家多提供更好的建议.
      

  3.   

    2:每个接收线程只接收一个字符串,sleep(10000)后,然后发回客户端.
    _______________________________________________________________你是说每个客户端有一个线程负责Socket接收吗?如果是的话,此方案肯定不能应付大量客户,二三百个定死无疑.
    另外,给一下你用的那个MSDN上的例子的链接,我看一下.
      

  4.   

    RedGoldFish(红金鱼) ( “周围啥都和谐,就差贴子没结”) 
    ////
    每个客户不用一个线程来维持...那怎么保持状态呀?
      

  5.   

    这个事情要分两部分说:1. Socket的Receive可以起一个线程,也可以用BeginReceive,后者是在有大量连接的时候采用的方法. Code Project 上有很多这种例子,比如这个就不错:http://www.codeproject.com/cs/internet/socketsincs.asp接受到新的连接后不能创建一个线程来维护它,这样性能很差,一个程序如果开几百了线程就离死不远了. 最好的方法是用Socket的异步功能: BeginXXXXX/EndXXXXX比如:public void SetupRecieveCallback( Socket sock )
    {
        try
        {
            AsyncCallback recieveData = new AsyncCallback( OnRecievedData );
            sock.BeginReceive( m_byBuff, 0, m_byBuff.Length, 
                               SocketFlags.None, recieveData, sock );
        }
        catch( Exception ex )
        {
            MessageBox.Show( this, ex.Message, "Setup Recieve Callback failed!" );
        }
    }public void OnRecievedData( IAsyncResult ar )
    {
        // Socket was the passed in object
        Socket sock = (Socket)ar.AsyncState;    // Check if we got any data
        try
        {
            int nBytesRec = sock.EndReceive( ar );
            if( nBytesRec > 0 )
            {
                // Wrote the data to the List
                string sRecieved = Encoding.ASCII.GetString( m_byBuff, 
                                                             0, nBytesRec );            // WARNING : The following line is NOT thread safe. Invoke is
                // m_lbRecievedData.Items.Add( sRecieved );
                Invoke( m_AddMessage, new string [] { sRecieved } );            // If the connection is still usable restablish the callback
                SetupRecieveCallback( sock );
            }
            else
            {
                // If no data was recieved then the connection is probably dead
                Console.WriteLine( "Client {0}, disconnected", 
                                   sock.RemoteEndPoint );
                sock.Shutdown( SocketShutdown.Both );
                sock.Close();
            }
        }
        catch( Exception ex )
        {
            MessageBox.Show( this, ex.Message, "Unusual error druing Recieve!" );
        }
    }
    此方法还有一个好处是.NET底层的Socket类库在你用异步时可以聪明到最大限度地利用通讯硬件上的线程和资源,对节省CPU资源很有帮助.
      

  6.   

    第二个问题是当接收了客户传来的Message之后(无论用上边我说的哪一种方法)应该如何处理:最简单的方法就是直接在接收的线程上,但如果你的服务器处理客户请求的操作比较复杂,时间很长,而且需要对共享资源加锁读写,就回产生大量线程同时并存的情况,这对服务器的性能有很大影响.我自己在处理这个问题的时候是在接收到客户传来的Message之后不直接处理,而是把它抛到一个队列里,这样一来接收线程就迅速释放; 另外整个服务器有一个单独的线程来处理队列里所有客户端的消息. 此方法在实际应用中效果相当不错.如果感兴趣,可以看一下我 Blog 里的那篇文章,有源代码:http://blog.csdn.net/RedGoldFish
      

  7.   

    Socket在服务端不要使用同步+多线程,不然性能会非常低!你可以去看看我的博客:http://wzd24.cnblogs.com