C# 为什么我的服务器';运行一段时间后,s的性能会受到影响吗?
我已经编写了服务器代码,它使用多线程(异步)从多个客户端(超过500个)连续接收来自服务器的数据。 它从所有客户端读取数据,并在多线程方面正常工作,并接收客户端发送的所有消息 有什么问题吗? 问题是,当我在1到2小时后继续从客户端读取数据时,我的服务器就会变慢。我的意思是,它不断增加CPU使用率(可能是因为解除了内存冻结…因为这里我们把所有东西都放在垃圾收集器上)。当我看到CPU内存在一段时间后从14%突然上升到80-100%。但它仍然从客户机接收数据(但有一些数据泄漏),但它仍然接收数据。我无法确定问题的原因 有人能告诉我是什么原因引起的吗 代码的重要部分是:C# 为什么我的服务器';运行一段时间后,s的性能会受到影响吗?,c#,multithreading,asynchronous,server,asyncsocket,C#,Multithreading,Asynchronous,Server,Asyncsocket,我已经编写了服务器代码,它使用多线程(异步)从多个客户端(超过500个)连续接收来自服务器的数据。 它从所有客户端读取数据,并在多线程方面正常工作,并接收客户端发送的所有消息 有什么问题吗? 问题是,当我在1到2小时后继续从客户端读取数据时,我的服务器就会变慢。我的意思是,它不断增加CPU使用率(可能是因为解除了内存冻结…因为这里我们把所有东西都放在垃圾收集器上)。当我看到CPU内存在一段时间后从14%突然上升到80-100%。但它仍然从客户机接收数据(但有一些数据泄漏),但它仍然接收数据。我无
public void StartServer()
{
try
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
server.Bind(ipep);
server.Listen(4);
AppendIncomingData(txtMsg, "Server Started..");
btnStart.Enabled = false;
lblStartDate.Text = DateTime.Now.ToString();
server.BeginAccept(new AsyncCallback(AcceptConn), server);
}
catch (Exception ex)
{
AppendIncomingData(txtError, ex.Message);
}
}
void AcceptConn(IAsyncResult ia)
{
Socket client;
try
{
Socket oldserver = (Socket) ia.AsyncState;
client = oldserver.EndAccept(ia);
StateObject state = new StateObject();
state.workSocket = client;
client.ReceiveTimeout = 1000;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveData), state);
server.BeginAccept(new AsyncCallback(AcceptConn), server);
}
catch (Exception ex)
{
AppendIncomingData(txtError, "AcceptConn Exception : " + ex.Message);
}
}
/// <summary>
/// StateObject Class to read data from Client
/// </summary>
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 512;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
public Int64 DeviceId = 0;
}
void ReceiveData(IAsyncResult ia)
{
StateObject state = (StateObject)ia.AsyncState;
Socket client = state.workSocket;
string sql = "";
string stringData = "";
try
{
recv = client.EndReceive(ia);
if (recv == 0)
{
client.Close();
server.BeginAccept(new AsyncCallback(AcceptConn), server);
return;
}
Array.Resize(ref state.buffer, StateObject.BufferSize);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveData), state);
} //End Try
catch (Exception ex)
{
AppendIncomingData(txtError, "ReceiveData Error : " + stringData + ": " + ex.Message);
client.Close();
server.BeginAccept(new AsyncCallback(AcceptConn), server);
}
}
public void AppendIncomingData(object dataControl, string str)
{
if (btnMsg.Text.ToUpper().Contains("START") == true)
return;
TextBox lst = (TextBox)dataControl;
if (lst.InvokeRequired)
{
AppendIncomingData_Delegate method = new AppendIncomingData_Delegate(AppendIncomingData);
lst.Invoke(method, new object[] { lst, str });
}
else
{
msglines += 1;
if (msglines > 500)
{
msglines = 0;
//lst.Clear();
txtError.Clear();
txtMsg.Clear();
}
lst.AppendText(Environment.NewLine + DateTime.Now.ToString() + " " + str);
}
}
public void StartServer()
{
尝试
{
服务器=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
IPEndPoint ipep=新IPEndPoint(IPAddress.Any,端口);
服务器绑定(ipep);
服务器。听(4);
AppendIncomingData(txtmg,“服务器已启动…”);
btnStart.Enabled=false;
lblStartDate.Text=DateTime.Now.ToString();
beginacept(新的异步回调(AcceptConn),server);
}
捕获(例外情况除外)
{
附录输入数据(TXError,例如消息);
}
}
无效接受连接(IAsyncResult ia)
{
套接字客户端;
尝试
{
Socket oldserver=(Socket)ia.AsyncState;
client=oldserver.EndAccept(ia);
StateObject状态=新的StateObject();
state.workSocket=客户端;
client.ReceiveTimeout=1000;
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveData),state);
beginacept(新的异步回调(AcceptConn),server);
}
捕获(例外情况除外)
{
AppendIncomingData(TXError,“AcceptConn异常:”+ex.Message);
}
}
///
///用于从客户端读取数据的StateObject类
///
公共类状态对象
{
//客户端套接字。
公共套接字工作组=null;
//接收缓冲区的大小。
public const int BufferSize=512;
//接收缓冲区。
公共字节[]缓冲区=新字节[BufferSize];
//接收到的数据字符串。
公共StringBuilder sb=新StringBuilder();
公共Int64设备ID=0;
}
无效接收数据(IAsyncResult ia)
{
StateObject状态=(StateObject)ia.AsyncState;
套接字客户端=state.workSocket;
字符串sql=“”;
字符串stringData=“”;
尝试
{
recv=client.EndReceive(ia);
如果(recv==0)
{
client.Close();
beginacept(新的异步回调(AcceptConn),server);
返回;
}
Resize(ref state.buffer、StateObject.BufferSize);
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveData),state);
}//结束尝试
捕获(例外情况除外)
{
AppendIncomingData(TXError,“ReceiveData错误:“+stringData+”:“+ex.Message”);
client.Close();
beginacept(新的异步回调(AcceptConn),server);
}
}
public void AppendIncomingData(对象数据控件,字符串str)
{
if(btnMsg.Text.ToUpper().包含(“开始”)==true)
返回;
TextBox lst=(TextBox)数据控件;
如果(需要第一次调用)
{
AppendIncomingData_委托方法=新的AppendIncomingData_委托(AppendIncomingData);
Invoke(方法,新对象[]{lst,str});
}
其他的
{
msglines+=1;
如果(msglines>500)
{
msglines=0;
//lst.Clear();
txtError.Clear();
txtMsg.Clear();
}
lst.AppendText(Environment.NewLine+DateTime.Now.ToString()+“”+str);
}
}
可能是什么问题?您描述的症状是内存使用量单调增加。也就是说,随着时间的推移,您的程序会分配越来越多的内存。最终,分配了如此多的内存,以至于其中一些必须交换到磁盘。但是,如果所有分配的内存仍在正常使用,则必须将该内存换回RAM,并将其他内存换出。这被称为“鞭打” 如果不能可靠地证明问题,就不可能确切地知道问题是什么。但代码中有几个明显的问题可能是原因:
beginacept()
,并且在打开连接时调用它。这意味着随着时间的推移,您将创建越来越多的未完成的接受I/O操作文本框
控件,在其中添加与服务器操作相关的状态消息(例如异常和客户端连接通知)。您已经注释掉了将清除相关文本框的行。当您清除txtError
和txtMsg
对象时,值得注意的是,您的接收完成回调方法对接收到的数据没有任何作用,这表明您出于某种原因在代码示例中忽略了该细节。因此,当您收到数据时,您也可能正在向其他文本框
写入数据,而没有清除该文本框
状态
对象。同样,你发布的代码没有任何作用
void AcceptConn(IAsyncResult ia)
{
Socket client;
try
{
Socket oldserver = (Socket) ia.AsyncState;
client = oldserver.EndAccept(ia);
StateObject state = new StateObject();
state.workSocket = client;
client.ReceiveTimeout = 1000;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveData), state);
server.BeginAccept(new AsyncCallback(AcceptConn), server);
}
catch (Exception ex)
{
AppendIncomingData(txtError, "AcceptConn Exception : " + ex.Message);
}
}