c# socket服务端程序开启一会cpu的占用率达到100%

sdkdxrc 2011-09-14 06:48:36
大侠们帮忙看一下,谢谢,分不是很多,以后有分了再追加给你们,谢谢,下面是我的主要代码:
开启监听: // UI 线程
_syncContext = SynchronizationContext.Current;

//启动后台线程去运行 Socket 服务
Thread thread = new Thread(new ThreadStart(StartupSocketServer));
thread.IsBackground = true;
thread.Start();

private void StartupSocketServer()
{

try
{
// 初始化 socket , 然后与端口绑定, 然后对端口进行监听
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listener.NoDelay = true;
_listener.SendBufferSize = ConstParameter.BUFFER_SIZE;
_listener.ReceiveBufferSize = ConstParameter.BUFFER_SIZE;
_listener.Bind(new IPEndPoint(IPAddress.Any, 4515)); // Silverlight 2.0 使用 Socket 只能连接 4502-4534 端口
_listener.Listen(100);
while (true)
{
// 重置 ManualResetEvent,由此线程来控制 ManualResetEvent,其它到这里来的线程请等待
// 为求简单易懂,本例实际上只有主线程会在这里循环运行
Thread.Sleep(500);
_connectDone.Reset();

// 开始接受客户端传入的连接
_listener.BeginAccept(new AsyncCallback(OnClientConnect), null);

// 阻止当前线程,直到当前 ManualResetEvent 调用 Set 发出继续信号
_connectDone.WaitOne();
}
}
catch (SocketException ex)
{

}

}

等待连接: private void OnClientConnect(IAsyncResult async)
{
// 当前 ManualResetEvent 调用 Set 以发出继续信号,从而允许继续执行一个或多个等待线程
_connectDone.Set();
ClientSocketPacket client = new ClientSocketPacket();
// 完成接受客户端传入的连接的这个异步操作,并返回客户端连入的 socket
client.Socket = _listener.EndAccept(async);

// 将客户端连入的 Socket 放进客户端 Socket 列表
_clientList.Add(client);
_syncContext.Post(ResultCallback, client.Socket.RemoteEndPoint);
try
{
// 开始接收客户端传入的数据
client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), client);
}
catch (SocketException ex)
{
// 处理异常
HandleException(client, ex);
}
//_listener.BeginAccept(new AsyncCallback(OnClientConnect), null);
}


接收数据: private void OnDataReceived(IAsyncResult async)
{
ClientSocketPacket client = async.AsyncState as ClientSocketPacket;
int count = 0;
try
{
// 完成接收数据的这个异步操作,并返回接收的字节数
if (client.Socket.Connected)
count = client.Socket.EndReceive(async);
}
catch (SocketException ex)
{
//MessageBox.Show(ex.Message.ToString());
HandleException(client, ex);
return;
}
// 把接收到的数据添加进收到的字节集合内
// 本例采用UTF8编码,中文占用3字节,英文占用1字节,缓冲区为32字节
// 所以如果直接把当前缓冲区转成字符串的话可能会出现乱码,所以要等接收完用户发送的全部信息后再转成字符串
foreach (byte b in client.Buffer.Take(count))
{
if (b == 0) continue; // 如果是空字节则不做处理

client.ReceivedByte.Add(b);
}

// 如果该 Socket 在网络缓冲区中没有排队的数据 并且 接收到的数据中有自定义的结束符时
if (client.Socket.Connected && client.Socket.Available == 0)//&& receivedString.Contains(_endMarker)
{

#region 发送信息
try
{
string jsonString = Encoding.UTF8.GetString(client.ReceivedByte.ToArray());
ChatMessage msg = JsonConvert.DeserializeObject<ChatMessage>(jsonString);
if (string.IsNullOrEmpty(msg.SenderIPAndPort))
{
msg.SenderIPAndPort = client.Socket.RemoteEndPoint.ToString();//得到发送者的IP和端口号
}
msg.Sendtime = DateTime.Now;
SendM = msg;
//发送信息
client.ReceivedByte.Clear();//清空以准备下次接收
SendMsg(msg);
Thread.Sleep(100);

}
catch (Exception ex)
{
//MessageBox.Show("aaa");
}
finally
{


}
#endregion
}

try
{
// 继续开始接收客户端传入的数据
if (client.Socket.Connected)
client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, 0, new AsyncCallback(OnDataReceived), client);
}
catch (SocketException ex)
{
HandleException(client, ex);
}
}
...全文
757 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sudianbo 的回复:]
死循环没有退出条件,长时间占用了CPU
[/Quote]

你说的死循环是?麻烦你详细指点下,谢谢了
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fengyarongaa 的回复:]
这是不可能的
就看你怎么用了
一般连接数也是有上限的
不是说你多线程就是线程越多就越好
根据实际情况 做不同的操作
你可以做IOCP完成端口 提升性能
[/Quote]

这一块我不是很懂,请你详细指点下,谢谢了
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 chenyingshu880603 的回复:]
看看客户端的构造函数中有什么while循环之类的一直在占用。
[/Quote]
客户端发送的代码如下:没有循环,谢谢了
void Send(ChatMessage msg)
{
try
{
string _msgJsonString = JsonConvert.SerializeObject(msg);
byte[] arrMsg = Encoding.UTF8.GetBytes(_msgJsonString);
if (AppGlobal.Instance.SocketMain.Connected)
{
// 设置需要发送的数据的缓冲区
AppGlobal.Instance.SocketMainArgs.BufferList =
new List<ArraySegment<byte>>()
{
new ArraySegment<byte>(arrMsg)// + _endMarker
};

// 异步地向服务端 Socket 发送消息
AppGlobal.Instance.SocketMain.SendAsync(AppGlobal.Instance.SocketMainArgs);
Thread.Sleep(100);
}
else
{
}
}
catch (Exception ex)
{
//OutPut(ex.Message.ToString());
}
}
Gemini Dean 2011-09-15
  • 打赏
  • 举报
回复
看看客户端的构造函数中有什么while循环之类的一直在占用。
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 chenyingshu880603 的回复:]
多线程也看情况而定,不用的就sleep掉,不要浪费资源
[/Quote]

我这里面只有一个开了一个啊?
Gemini Dean 2011-09-15
  • 打赏
  • 举报
回复
多线程也看情况而定,不用的就sleep掉,不要浪费资源
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
谢谢大家的回答,我用一个性能软件监测了一下,发现是我的接收数据函数private void OnDataReceived(IAsyncResult async)用一会之后就占用之量的CPU,但是我没有找到解决办法,请各位高手帮我看一下,或者加我的QQ,一起解决一下,万分感谢各位大侠……
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sunny906 的回复:]
用了异步回调,就不要用while (true){}
[/Quote]

这个地方我试过用异步,也是会出现cpu 90%多的情况
sdkdxrc 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhantianyou 的回复:]
while (true)
这个循环里头你要加一个Thread.Sleep(时间),不然程序直接堵死在这里边,当然CPU就100%
[/Quote]


while (true)
{
// 重置 ManualResetEvent,由此线程来控制 ManualResetEvent,其它到这里来的线程请等待
// 为求简单易懂,本例实际上只有主线程会在这里循环运行
Thread.Sleep(500);
_connectDone.Reset();

// 开始接受客户端传入的连接
_listener.BeginAccept(new AsyncCallback(OnClientConnect), null);

// 阻止当前线程,直到当前 ManualResetEvent 调用 Set 发出继续信号
_connectDone.WaitOne();
}
}
catch (SocketException ex)
{

}
已经加了啊……
ycproc 2011-09-15
  • 打赏
  • 举报
回复
这是不可能的
就看你怎么用了
一般连接数也是有上限的
不是说你多线程就是线程越多就越好
根据实际情况 做不同的操作
你可以做IOCP完成端口 提升性能
sunny906 2011-09-15
  • 打赏
  • 举报
回复
用了异步回调,就不要用while (true){}
zhantianyou 2011-09-15
  • 打赏
  • 举报
回复
while (true)
这个循环里头你要加一个Thread.Sleep(时间),不然程序直接堵死在这里边,当然CPU就100%
_三皮_ 2011-09-15
  • 打赏
  • 举报
回复
死循环没有退出条件,长时间占用了CPU
微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。 微信小程序系统教程共有“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]——核心技术”、“微信小程序系统教程[阶段]客服消息+微信支付+九宝电商系统”。 “微信小程序系统教程[阶段]全套课程”包含: 1.微信小程序系统教程[阶段]_客服消息 2.微信小程序系统教程[阶段]_微信支付 3.微信小程序系统教程[阶段]_九宝电商系统 学习“微信小程序系统教程[阶段]”要求有微信小程序的基础。建议先学习“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]”,后在报名“微信小程序系统教程[阶段]”。 阶段讲解的客服消息,是针对小程序的。后台程序用接近底层的技术,没有使用三方技术。这样降低同学们学习成本。 微信支付,这部分课程很有难度,要求同学们认真听讲,有不会的技术问题可以请教老师。购买课程后请联系老师,提供单号,给你源程序。 九宝电商系统是一套十分适和学习、项目的课程。既可以系统的学习微信小程序相关知识,还可以修改后上线。 “微信小程序系统教程[中级阶段]——核心技术”重点讲解微信小程序事件、组件、API 微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。 购买课程的同学,可赠送就九宝老师编写的《微信小程序开发宝典》。 购课请咨询qq2326321088

110,539

社区成员

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

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

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