gpt4 book ai didi

c# - .NET TCP 服务器稳定性问题

转载 作者:可可西里 更新时间:2023-11-01 02:53:02 25 4
gpt4 key购买 nike

我已经使用 TcpListener 和 SocketClient 构建了一个基本的 .NET 服务器-客户端基础结构。它是多线程和异步的。问题是,当同时连接超过 30 个客户端时,服务器有时会崩溃。

尽管我确实使用了相当多的 Try-Catch block 来确保记录所有异常,但我仍无法找到崩溃的原因。

所以我在想,我可能在服务器代码中做错了概念上的事情。我希望你们能帮助我找到这些崩溃的原因。代码如下:

启动服务器并监听连接:

 public void StartServer()
{
isConnected = true;
listener.Start();
connectionThread = new Thread(new ThreadStart(ListenForConnection));
connectionThread.Start();
}

private void ListenForConnection()
{
while (isConnected)
{
try
{
TcpClient client = listener.AcceptTcpClient();
ClientConnection connection = new ClientConnection(this, client);
connections.Add(connection);
}
catch (Exception ex)
{
log.Log("Exception in ListenForConnection: " + ex.Message, LogType.Exception);
}
}
}

ClientConnection 类:

 public class ClientConnection : IClientConnection
{
private TcpClient client;
private ISocketServer server;
private byte[] data;
private object metaData;

public TcpClient TcpClient
{
get { return client; }
}

internal ClientConnection(ISocketServer server, TcpClient client)
{
this.client = client;
this.server = server;

data = new byte[client.ReceiveBufferSize];

lock (client.GetStream())
{
client.GetStream().BeginRead(data, 0, client.ReceiveBufferSize, ReceiveMessage, null);
}
}

internal void ReceiveMessage(IAsyncResult ar)
{
int bytesRead;

try
{
lock (client.GetStream())
{
bytesRead = client.GetStream().EndRead(ar);
}

if (bytesRead < 1)
return;

byte[] toSend = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
toSend[i] = data[i];

// Throws an Event with the data in the GUI Dispatcher Thread
server.ReceiveDataFromClient(this, toSend);

lock (client.GetStream())
{
client.GetStream().BeginRead(data, 0, client.ReceiveBufferSize, ReceiveMessage, null);
}
}
catch (Exception ex)
{
Disconnect();
}
}

public void Disconnect()
{
// Disconnect Client
}


}

并将数据从服务器发送到一个或所有客户端:

public void SendDataToAll(byte[] data)
{
BinaryWriter writer;

try
{
foreach (IClientConnection connection in connections)
{
writer = new BinaryWriter(connection.TcpClient.GetStream());
writer.Write(data);
writer.Flush();
}
}
catch (Exception ex)
{
// Log
}
}

public void SendDataToOne(IClientConnection client, byte[] data)
{
BinaryWriter writer;

try
{
writer = new BinaryWriter(client.TcpClient.GetStream());
writer.Write(data);
writer.Flush();
}
catch (Exception ex)
{
// Log
}
}

有时服务器崩溃了,我真的不知道从哪里开始寻找问题。如果需要,我可以提供更多代码。

非常感谢任何帮助:-)安德烈

最佳答案

您应该使对连接字段的访问成为线程安全的。

在 SendData 中,您将遍历连接并将数据发送到每个客户端。如果在执行 foreach 循环时有新的客户端连接,您将收到异常消息“集合已修改;枚举操作可能无法执行”,因为在迭代集合时集合已被修改,这是不允许的。

将SendDataToAll中的行修改为

foreach (IClientConnection connection in connections.ToList())

使问题消失(解决方案由 Collection was modified; enumeration operation may not execute 提供)。

关于c# - .NET TCP 服务器稳定性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3668757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com