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

问题描述

我使用C#的TCPlistener写了一个TCP服务端的程序,用来向连接到服务端的客户端发送数据的,客户端发送不同的请求就发送相应的数据,没有请求数据就什么也不发送;发送的数据是从另一个端口接收到的UDP的报文解析后的数据服务端程序包括接收及解析UDP报文,和TCPlistener监听(有连接请求就建立一个线程为这个连接服务,连接断开就终止线程)现在当服务端程序启动,就开始接收UDP报文并解析,如果有连接请求,就创建线程并为连接服务,当模拟器客户端断开连接,CPU使用率就会迅速增长到80%-90%

解决方案

解决方案二:
引用楼主zym19825的回复:

有连接请求就建立一个线程为这个连接服务

Socket的异步操作不像是你这么搞的,看看BeginXXX/EndXXX或者XXXAsync这些接口的例子
解决方案三:
引用1楼shingoscar的回复:

Quote: 引用楼主zym19825的回复:
有连接请求就建立一个线程为这个连接服务

Socket的异步操作不像是你这么搞的,看看BeginXXX/EndXXX或者XXXAsync这些接口的例子

我也分不清异步同步,这是服务端的一部分代码IPAddress_ip=Dns.GetHostAddresses(Dns.GetHostName())[1];//可能有多个,此时的IP是本地IP_tcpl=newTcpListener(IPAddress.Any,_port);_tcpl.Start();//开始侦听传入的连接请求。Console.WriteLine("服务器已启动,正在监听...n");Console.WriteLine(string.Format("服务器IP:{0}t端口号:{1}n",_ip,_port));while(true){byte[]packetBuff=newbyte[_maxPacket];//接收数据缓冲区大小64K//AcceptSocket是一个阻止方法,该方法返回可用于发送和接收数据的Socket。//如果希望避免阻止,请使用Pending方法来确定传入连接队列中的连接请求是否可用。//返回的Socket是使用远程主机的IP地址和端口号初始化的。//您可以使用Socket类中任何可用的Send和Receive方法与远程主机进行通信。//------------使用Socket后,请确保调用其Close方法。如果应用程序相对简单,-----------//请考虑使用AcceptTcpClient方法代替AcceptSocket方法。//TcpClient提供了一些通过网络在阻止同步模式下发送和接收数据的简单方法。SocketnewClient=_tcpl.AcceptSocket();//本地TcpListener接受新的请求//返回的Socket是使用远程主机的IP地址和端口号初始化的//newClient.Receive(packetBuff);//将接受的远程SOCKET,将数据存入接受缓冲区IPAddressip=((System.Net.IPEndPoint)newClient.RemoteEndPoint).Address;stringuserName=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);//-----------------------stringsvrlog=string.Format("[系统消息]新用户{0}在{1}已连接...当前在线人数:{2}rnrn",userName,DateTime.Now,_transmit_tb.Count);Console.WriteLine(svrlog);//------------------------ThreadclientThread=newThread(newParameterizedThreadStart(ThreadFunc));clientThread.Start(userName)现在已经解决了,是我没有判断正常断开连接的情况,所以当客户端正常断开后,服务端程序创建的线程没有关闭

时间: 2024-09-08 20:11:52

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

udp-UDP跨路由器通信,客户端无法收到服务端发送的UDP包

问题描述 UDP跨路由器通信,客户端无法收到服务端发送的UDP包 本人新手,正做一个UDP跨路由通信项目,遇如下问题:服务端(192.168.0.85)与路由器在同一网段,客户端(192.168.1.103)在该路由器组成的局域网内,现服务端可以接收到客户端发送的UDP包,但客户端无法收到服务端的UDP包.请问客户端发送的UDP包需怎样设置(IP/端口)?(PS:服务端与客服端在同一局域网内是可以UDP通信的) 以下是我的UDP设置客户端--目标IP:192.168.0.85----目标端口10

请问Socket客户端如何像服务端一样自动监听远程终端是否连接上

问题描述 今天偶然发现Socket服务端可以通过Socket.Accept();自动检测远程终端是否连接,即使网络中断也不会报异常,当网络恢复后又自动连接上,不用做任何判断.抛异常和显示重连.请问客户端如何像服务端一样实现上述功能? 解决方案 解决方案二: 解决方案三:参考你需要的解决方案四:Accept是等待"任意"客户端连接.如果网络中断,自然就没有客户端连接.此时它抛异常干什么?人家根本没有的逻辑,你硬说它有那个"抛异常.显示重联",是何道理?解决方案五:引用

wcf-WCF,客户端上传图片到服务端,然后再存放到数据库中的image字段中。

问题描述 WCF,客户端上传图片到服务端,然后再存放到数据库中的image字段中. WCF的问题.我现在在需要上传相片到数据库中存储,数据库中想用image数据类型来存储,不是用相片的路径.功能要求是在客户端首先将图片显示在PictuerBox中,然后点击上传.上传成功后需要从数据库中把相片取出来显示在PictuerBox).求案例 解决方案 http://blog.sina.com.cn/s/blog_a339e95f0101aakx.html 传输,直接传字节数组就可以了. 解决方案二: h

android-关于socket编程 客户端不能接受服务端信息问题

问题描述 关于socket编程 客户端不能接受服务端信息问题 private void send() { try { tvGetContent.append("我说:" + etSendContent.getText().toString() + "n"); writer.write(etSendContent.getText().toString() + "n"); writer.flush(); etSendContent.setText(&

extjs4-使用Ext.form.action.Action ,断开与服务端的连接,再提交,提示框无法关闭

问题描述 使用Ext.form.action.Action ,断开与服务端的连接,再提交,提示框无法关闭 使用Ext.form.action.Action 来提交数据,提交前断开与服务端的连接,再提交.waitMessage的信息一直显示,该怎么关闭啊 解决方案 配置timeout 和failure,超时后触发failure事件,隐藏起来就行了~ timeout单位为妙..

C# Scoket通讯 客户端如何读取服务端发来的消息

问题描述 C#Scoket通讯客户端如何读取服务端发来的消息?请高手指点! 解决方案 解决方案二:你接收过来后,根据协议拆分分析就可以了.解决方案三: 解决方案四:Encoding.ASCII.GetString解决方案五:定义好发送协议,接受的时候注意分包,粘包的处理解决方案六:解析啊数据格式解决方案七:客户端有两种基本的通讯时序模式.一种"短链接.一问一答"模式的.客户端首先发送消息,然后Receive,得到回复之后就关闭连接.另一种是长连接的,这个时候会异步地Receive,不管

soket客户端如何获得服务端的ip,然后再根据ip地址连接?

问题描述 soket客户端如何获得服务端的ip,然后再根据ip地址连接? 解决方案 解决方案二:局域网就发广播咯,广域网就只有用域名了

winform-Winform客户端和Android客户端同时使用一个服务端,后端(C#)采用什么技术实现?

问题描述 Winform客户端和Android客户端同时使用一个服务端,后端(C#)采用什么技术实现? asp.net Webapi作为Android服务端(个人想法),Winform使用什么服务端呢?如果要求数据同步,使用观察者模式?使用的协议也是个问题.求大神指点! 解决方案 web API都可以,只要你 的服务器是什么平台就选对应的,比如windows就用C#等开发web API这样各种客户端都可以访问 解决方案二: 考虑到android调用的方便,建议直接用asp.net mvc返回js

asifromdatarequest-iOS客户端向C#服务端post数据问题

问题描述 iOS客户端向C#服务端post数据问题 C#服务端要求接收的数据包格式为UInt16类型的2位,UInt32类型的4位,String类型的8位,Byte类型的1位... 目前我用NSMutableData组成请求数据包发送给C#服务端,但是返回结果错误提示,高手赐教下,这种post请求要如何发送呢? 我现在是用ASIHTTPRequest进行post. 问题应该出在组装请求数据这里. 我目前是这样组装的: NSMutableData *dt = [[NSMutableData all