服务器套接字问题(示例代码注释)

时间:2009-10-09 07:51:33

标签: c# networking

我正在为游戏服务器开发一些额外的东西,但我不理解我收到的代码(但它有效)。如果有人能向我解释,为什么(在recievedata方法中)有套接字列表清除然后再填充,我会很高兴。我只是看不出这一点。

this.mReceiveDataThread = new System.Threading.Thread(this.ReceiveData);

           protected void ReceiveData()
        {
            List<System.Net.Sockets.Socket> sockets = new List<System.Net.Sockets.Socket>();
            bool noClients = false;
            while (true)
            {
                if (noClients)
                {
                    System.Threading.Thread.Sleep(RECEIVE_DATA_NO_CLIENT_WAIT_TIME);
                    noClients = false;
                }
                this.mClientsSynchronization.AcquireReaderLock(-1);
                try
                {
                    if (this.mClients == null || this.mClients.Count == 0)
                    {
                        noClients = true;
                        continue;
                    }
                    sockets.Clear(); 
                    for (int i = 0; i < this.mClientsValues.Count; i++)
                    {
                        Client c = this.mClientsValues[i];
                        if (!c.IsDisconnected && !c.ReadingInProgress)
                        {
                            sockets.Add(c.Socket);
                        }
                    }
                    if (sockets.Count == 0)
                    {
                        // noClients = true;
                        continue;
                    }
                }
                finally
                {
                    this.mClientsSynchronization.ReleaseReaderLock();
                }
                try
                {
                    //System.Net.Sockets.Socket.Select(sockets, null, null, RECEIVE_DATA_TIMEOUT);
                    SocketSelect.Select(sockets, null, null, RECEIVE_DATA_TIMEOUT);
                    foreach (System.Net.Sockets.Socket s in sockets)
                    {
                        Client c = this.mClients[s]; //mClients-dictionary<socket,client>
                        if (!c.SetReadingInProgress())
                        {
                            System.Threading.ThreadPool.QueueUserWorkItem(c.ReadData);
                        }
                    }
                }
                catch (Exception e)
                {
                    this.OnExceptionCaught(this, new ExceptionCaughtEventArgs(e, "Exception when reading data."));
                }
            }
        }

1 个答案:

答案 0 :(得分:1)

在循环中使用套接字列表从mClients中提取仍然连接的客户端对象。在每次循环迭代时清除套接字列表,以便可以检查mClients以排除任何已经读取的已断开连接的客户端或客户端。

取出线程锁定机制和SocketSelect调用循环可归结为下面的代码,这可能更容易理解。

mClients.Where(c => !c.IsDisconnected && !c.ReadingInProgress).ToList().ForEach(c=> {
    if (!c.SetReadingInProgress())  {
        ThreadPool.QueueUserWorkItem(c.ReadData);                        
    }
});