问题描述:ListenClientConnect过程 Exception of type 'System.OutOfMemoryException' was thrown.
运行环境:有100多个客户端,不出意外,长时间在线,心跳包是60秒一个,数据是5分钟一个
代码如下 之前出现过类似问题 加了GC.Collect(); 但是还是没解决
private void ListenClientConnect(object ServerSocket)
{
while (true)
{
try
{
Socket socket = (Socket)ServerSocket;
Socket clientSocket = socket.Accept();
Thread receiveThread = new Thread(receivesocketmessage);
receiveThread.IsBackground = true;
receiveThread.Start(clientSocket);
}
catch (Exception er) { Wlog wlog = new Wlog(); wlog.errlog("ListenClientConnect" + " " + er.Message); GC.Collect(); }
}
}
private void receivesocketmessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket;
byte[] result=new byte[1024];
DateTime dt = DateTime.Now;
while (true)
{
try
{
if ((DateTime.Now - dt).TotalSeconds > 70)
{
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
} //根据超时时间结束线程
int receiveNumber = 0;
//通过clientSocket接收数据
try
{
receiveNumber = myClientSocket.Receive(result);
}
catch (Exception er)
{
Wlog wlog = new Wlog(); wlog.errlog("myClientSocket.Receive " + er.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
}
//Console.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
string str = "";
if (receiveNumber > 0)
{
dt = DateTime.Now;
for (int i = 0; i < receiveNumber; i++)
{ str += result[i].ToString("X").PadLeft(2, '0'); }
jiexiPara jp = new jiexiPara(str, DateTime.Now, 1, "");
baowenjiexi(jp, clientSocket);
}
}
catch (Exception er) { Wlog wlog = new Wlog(); wlog.errlog("receivesocketmessage "+er.Message); }
//Thread.Sleep(80);
}
GC.Collect();
}
------解决思路----------------------
你连哪一行抛出异常都不知道,我相信你更没有调试过抛出异常的行中的各种变量,以及顺着调用堆栈去逐层分析变量吧?!
删除你的try....catch,写实际的测试程序去反复、打乱次序、随机数据、并行地测试1万次,然后使用vs调试器去调试你的程序。
最初级地编程技能,你得知道异常抛自哪一行、哪一个变量上吧?!
------解决思路----------------------
可能性很多,最大的是内存碎片太多。
可以尝试一下重用那个长度为 1024 的缓冲区。
线程太多也可能是个问题,要不尝试一下用异步?
------解决思路----------------------
异常日志写得不详细啊。ex.message给出的信息是不够的,一般来说异常的日志最好是ex.ToString(),这样可以获得堆栈信息,这样你就可以知道是哪个方法抛出的异常,然后在抛异常的方法里设置断点,调试就知道了。
------解决思路----------------------
同样在做Socket程序,没遇到过这个问题,帮顶。指出一个问题:
myClientSocket.Shutdown(SocketShutdown.Both);
这段代码在网络中断时会报错。