我正在为游戏服务器开发一些额外的东西,但我不理解我收到的代码(但它有效)。如果有人能向我解释,为什么(在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."));
}
}
}
答案 0 :(得分:1)
在循环中使用套接字列表从mClients中提取仍然连接的客户端对象。在每次循环迭代时清除套接字列表,以便可以检查mClients以排除任何已经读取的已断开连接的客户端或客户端。
取出线程锁定机制和SocketSelect调用循环可归结为下面的代码,这可能更容易理解。
mClients.Where(c => !c.IsDisconnected && !c.ReadingInProgress).ToList().ForEach(c=> {
if (!c.SetReadingInProgress()) {
ThreadPool.QueueUserWorkItem(c.ReadData);
}
});