C#TCP通信时模拟客户端断开后服务端的CPU使用率从45%上升到80%-90%

zym19825 2015-08-31 06:09:56
我使用C#的TCPlistener写了一个TCP服务端的程序,用来向连接到服务端的客户端发送数据的,客户端发送不同的请求就发送相应的数据,没有请求数据就什么也不发送;

发送的数据是从另一个端口接收到的UDP的报文解析后的数据

服务端程序包括接收及解析UDP报文,和TCPlistener监听(有连接请求就建立一个线程为这个连接服务,连接断开就终止线程)


现在当服务端程序启动,就开始接收UDP报文并解析,如果有连接请求,就创建线程并为连接服务,当模拟器客户端断开连接,CPU使用率就会迅速增长到80%-90%

...全文
180 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zym19825 2015-09-14
  • 打赏
  • 举报
回复
引用 1 楼 shingoscar 的回复:
[quote=引用 楼主 zym19825 的回复:] 有连接请求就建立一个线程为这个连接服务
Socket的异步操作不像是你这么搞的,看看BeginXXX/EndXXX或者XXXAsync这些接口的例子[/quote] 我也分不清异步同步,这是服务端的一部分代码 IPAddress _ip = Dns.GetHostAddresses(Dns.GetHostName())[1];//可能有多个,此时的IP是本地IP _tcpl = new TcpListener(IPAddress.Any, _port); _tcpl.Start();//开始侦听传入的连接请求。 Console.WriteLine("服务器已启动,正在监听...\n"); Console.WriteLine(string.Format("服务器IP:{0}\t端口号:{1}\n", _ip, _port)); while (true) { byte[] packetBuff = new byte[_maxPacket];// 接收数据缓冲区大小64K //AcceptSocket 是一个阻止方法,该方法返回可用于发送和接收数据的 Socket。 //如果希望避免阻止,请使用 Pending 方法来确定传入连接队列中的连接请求是否可用。 //返回的 Socket 是使用远程主机的 IP 地址和端口号初始化的。 //您可以使用 Socket 类中任何可用的 Send 和 Receive 方法与远程主机进行通信。 //------------使用 Socket 后,请确保调用其 Close 方法。如果应用程序相对简单,----------- //请考虑使用 AcceptTcpClient 方法代替 AcceptSocket 方法。 //TcpClient 提供了一些通过网络在阻止同步模式下发送和接收数据的简单方法。 Socket newClient = _tcpl.AcceptSocket();//本地TcpListener 接受新的请求 //返回的 Socket 是使用远程主机的 IP 地址和端口号初始化的 //newClient.Receive(packetBuff);//将接受的远程SOCKET,将数据存入接受缓冲区 IPAddress ip = ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Address; string userName = ip.ToString() + ":" + ((System.Net.IPEndPoint)newClient.RemoteEndPoint).Port; //验证是否为唯一用户,有了就发送失败命令给请求客户 if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(userName)) { newClient.Send(Encoding.Unicode.GetBytes("cmd::Failed")); continue; } else { newClient.Send(Encoding.Unicode.GetBytes("cmd::Successful")); } //将新连接加入转发表并创建线程为其服务 _transmit_tb.Add(userName, newClient); //----------------------- string svrlog = string.Format("[系统消息]新用户 {0} 在 {1} 已连接... 当前在线人数: {2}\r\n\r\n", userName, DateTime.Now, _transmit_tb.Count); Console.WriteLine(svrlog); //------------------------ Thread clientThread = new Thread(new ParameterizedThreadStart(ThreadFunc)); clientThread.Start(userName) 现在已经解决了,是我没有判断正常断开连接的情况,所以当客户端正常断开后,服务端程序创建的线程没有关闭
Poopaye 2015-08-31
  • 打赏
  • 举报
回复
引用 楼主 zym19825 的回复:
有连接请求就建立一个线程为这个连接服务
Socket的异步操作不像是你这么搞的,看看BeginXXX/EndXXX或者XXXAsync这些接口的例子

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧