从网上找的一段代码,用的线程监听 Socket +while
客户端连接到300+的时候 CPU就快满了 不知道哪里出的问题 求大神给处理处理啊 看看在这代码的基础啥 咋改啊?
贴出代码
/// <summary> /// 监听客户端请求的方法; /// </summary> void WatchConnecting() { while (true) // 持续不断的监听客户端的连接请求; { Socket sokConnection = null; try { // 开始监听客户端连接请求,Accept方法会阻断当前的线程; sokConnection = socketWatch.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字; } catch (Exception ex) { //提示套接字监听异常 ShowMsg("异常:" + ex.Message); break; } // 想列表控件中添加客户端的IP信息; lbOnline.Items.Add(sokConnection.RemoteEndPoint.ToString()); zxnum = zxnum + 1; label1.Text = zxnum.ToString(); // 将与客户端连接的 套接字 对象添加到集合中; dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection); ShowMsg("客户端连接成功!"); Thread thr = new Thread(RecMsg); thr.IsBackground = true; thr.Start(sokConnection); dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); // 将新建的线程 添加 到线程的集合中去。 } } void RecMsg(object sokConnectionparn) { Socket sokClient = sokConnectionparn as Socket; while (true) { // 定义一个2M的缓存区; byte[] arrMsgRec = new byte[1024 * 1024 * 2]; // 将接受到的数据存入到输入 arrMsgRec中; int length = -1; try { length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度; if (length > 0) { string strMsg = System.Text.Encoding.ASCII.GetString(arrMsgRec);// 将接受到的字节数据转化成字符串; //ShowMsg(strMsg); } else { // 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(sokClient.RemoteEndPoint.ToString()); // 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString()); // 从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString()); zxnum = zxnum - 1; label1.Text = zxnum.ToString(); break; } } catch (SocketException se) { ShowMsg("异常:" + se.Message); // 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(sokClient.RemoteEndPoint.ToString()); // 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString()); // 从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString()); zxnum = zxnum - 1; label1.Text = zxnum.ToString(); break; } catch (Exception e) { ShowMsg("异常:" + e.Message); // 从 通信套接字 集合中删除被中断连接的通信套接字; dict.Remove(sokClient.RemoteEndPoint.ToString()); // 从通信线程集合中删除被中断连接的通信线程对象; dictThread.Remove(sokClient.RemoteEndPoint.ToString()); // 从列表中移除被中断的连接IP lbOnline.Items.Remove(sokClient.RemoteEndPoint.ToString()); zxnum = zxnum - 1; label1.Text = zxnum.ToString(); break; } Thread.Sleep(10); } }
按道理不会,这种只是连接比较慢。
如果你客户端发送频次非常高,有可能。
还有就是连接初期,你上面的代码不能反映消耗情况
(
如:label1.Text = zxnum.ToString(); // 将与客户端连接的 套接字 对象添加到集合中; dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection); ShowMsg("客户端连接成功!");
),然而这个时候都涌进来。
还有这里的写法问题:这不是游戏,操作ui通常需要Invoke,即使你设置允许多线程访问不排除锁住的问题;
用SocketAsyncEventArgs
官网有例子https://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx
具体还需要自己实现
这个SocketAsyncEventArgs是微软对iocp的封装,可以实现高并发socket
当你客户端连接到300的时候,统计一下有多少个线程在跑RecMsg?另外socket用完要调用close释放
可以考虑用线程池管理你的线程 这样会好一点 如果要对UI操作建议用Invoke