本人已经用C#实现了多个客户端连接服务端的问题,但我还想限制客户端的连接数。例如我希望同时连接到服务端的数目为2,若第三个发起连接请求时会失败。  
本人已基本想出解决限制客户端的连接数的方法,但是出现一个问题就是明明我是设置只允许连接N个,却可以连接N+1个,但第N+2个时就会失败,我没查出原因。  
我的代码如下:  
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
using System.Net;  
using System.Net.Sockets;  
using System.Threading;  
namespace TCPSERVER  
{  
    public partial class FrmServer : Form  
    {  
        private Socket m_ServerListener = null;  
        private ClientInformationCls[] m_clientList;  
        delegate void SetTextCallback(string strText);  
        private const int MAX_CLIENT = 1;              //client connnecting max number          public FrmServer()  
        {  
            InitializeComponent();  
        }         private static IPAddress GetServerIP()  
        {              IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName());              return ieh.AddressList[0];          }         private void BeginListen()  
        {  
            int intPort =8000;              m_clientList=new  ClientInformationCls[ MAX_CLIENT ];              IPAddress ServerIp = GetServerIP();              IPEndPoint iep = new IPEndPoint(ServerIp, intPort);  
            m_ServerListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
            m_ServerListener.Bind(iep);  
            m_ServerListener.Listen(1);  
        }          private void btnBeginListen_Click(object sender, EventArgs e)  
        {  
              
              
            try  
            {  
                BeginListen();  
                lstServerStatus.Items.Add("Server is starting listening....");                  InitClientList();                  Thread acceptThread = new Thread(new ThreadStart(AcceptClientThread));  
                acceptThread.Start();  
   
                
            }  
            catch (SocketException  ex)  
            {  
                MessageBox.Show(ex.ToString());  
            }  
            catch (Exception ex)  
            {  
                MessageBox.Show(ex.ToString());  
            }  
        }          private void AcceptClientThread()  
        {  
            int intClientIndex;              Thread.CurrentThread.IsBackground = true;              try  
            {  
                while (true)  
                {  
                    intClientIndex = GetFreeClient();  
                    if (intClientIndex != -1)  
                    {  
                        m_clientList[intClientIndex].IsIdle = false;  
                        Socket clientSocket = m_ServerListener.Accept();  
                        IPEndPoint remoEP = (IPEndPoint)clientSocket.RemoteEndPoint;  
                      
                        m_clientList[intClientIndex].ClientIP = remoEP.Address.ToString();  
                        m_clientList[intClientIndex].ClientSocket = clientSocket;  
                        SetText("connecting from " + m_clientList[intClientIndex].ClientIP);                          Thread DealingThread = new Thread(new ParameterizedThreadStart(RcvSndThread));                          DealingThread.Start(m_clientList[intClientIndex]);                      }  
                }  
            }              catch (SocketException ex)  
            {  
                MessageBox.Show(ex.ToString());  
            }  
            catch (Exception ex)  
            {  
                MessageBox.Show(ex.ToString());  
            }          }          private void RcvSndThread(object obj)  
        {  
            Thread.CurrentThread.IsBackground = true;  
            ClientInformationCls clientTmp = (ClientInformationCls)obj;  
       
            byte[] buffer = new byte[1024];  
            int intRcvCount;              try  
            {  
                while (clientTmp.ClientSocket.Connected == true)  
                {  
                    intRcvCount = clientTmp.ClientSocket.Receive(buffer);  
                    SetText(Encoding.Default.GetString(buffer, 0, intRcvCount));                  }  
            }              catch (SocketException ex)  
            {  
                MessageBox.Show(ex.ToString());  
            }              catch (Exception ex)  
            {  
                MessageBox.Show(ex.ToString());  
            }  
                   }          private void  InitClientList()  
        {  
            int i = 0;  
            for (i=0; i   <= m_clientList.Length-1; i++)  
            {  
                m_clientList[i] = new ClientInformationCls();  
                m_clientList[i].ClientHostName="";  
                m_clientList[i].ClientIP = "";  
                m_clientList[i].Index=i;  
                m_clientList[i].IsIdle = true;  
                m_clientList[i].ClientSocket = null;  
            }  
        }          private int GetFreeClient()  
        {  
            int i = 0;  
             
            for (i = 0; i   <= m_clientList.Length - 1; i++)  
            {  
                if (m_clientList[i] == null) return -1;  
                 
                if (m_clientList[i].IsIdle == true)  
                {  
                    return i;  
                }  
            }  
            return -1;  
        }          private void SetText(string strText)  
        {  
            if (this.lstServerStatus.InvokeRequired)  
            {  
                SetTextCallback d = new SetTextCallback(SetText);  
                this.Invoke(d, new object[] { strText });  
            }  
            else  
            {  
                this.lstServerStatus.Items.Add(strText);  
            }  
        }      }  
}  
其中 ClientInformationCls是本人自定义的类,一个保存客户端SOCKET的连接信息,其中有个IsIdle属性用来记录该SOCKET是否可用  
using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Net.Sockets;  
namespace TCPSERVER  
{  
    class ClientInformationCls  
    {  
        
        private int m_intClientIndex;             //client's index   
        private string m_strClientIP;  
        private string m_strClientHostName;  
        private bool  m_blnIsIdle;  
        private Socket m_clientSocket;  
        public int Index  
        {  
           get{return m_intClientIndex;}  
           set{m_intClientIndex=value;}  
        }          public string ClientIP  
        {  
            get { return m_strClientIP; }  
            set { m_strClientIP = value; }  
        }          public string ClientHostName  
        {  
            get { return m_strClientHostName; }  
            set { m_strClientHostName = value; }  
        }          public bool IsIdle  
        {  
            get { return m_blnIsIdle; }  
            set { m_blnIsIdle = value; }  
        }  
        public Socket ClientSocket  
        {  
            get { return m_clientSocket; }  
            set { m_clientSocket = value; }  
        }  
    }  
}  我在AcceptClientThread函数中调用了  
intClientIndex = GetFreeClient();   
如果intClientIndex=-1的话表示不能在允许其他的客户端连接,这样就不会创建新的线程了,  
现在我的问题是我明明创建了数组   m_clientList=new  ClientInformationCls[ MAX_CLIENT ];   
而MAX_CLIENT初始化时已经设置为1了,也就是说服务端最大的连接数为MAX_CLIENT=1,  
而我测试的时候,服务端最大的连接数为MAX_CLIENT+1了,请高手帮忙看看