首页 新闻 会员 周边

用Socket 加 while 没连接几个客户端CPU就占用很高了 求大神帮忙

0
悬赏园豆:100 [已解决问题] 解决于 2018-05-12 08:06

从网上找的一段代码,用的线程监听 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);
            }
        }
wopool的主页 wopool | 初学一级 | 园豆:14
提问于:2018-05-10 08:12
< >
分享
最佳答案
0

按道理不会,这种只是连接比较慢。

如果你客户端发送频次非常高,有可能。

还有就是连接初期,你上面的代码不能反映消耗情况

如:label1.Text = zxnum.ToString(); // 将与客户端连接的 套接字 对象添加到集合中; dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection); ShowMsg("客户端连接成功!");

 

),然而这个时候都涌进来。

还有这里的写法问题:这不是游戏,操作ui通常需要Invoke,即使你设置允许多线程访问不排除锁住的问题;

收获园豆:60
花飘水流兮 | 专家六级 |园豆:13560 | 2018-05-11 17:45
其他回答(3)
0

用SocketAsyncEventArgs

官网有例子https://msdn.microsoft.com/zh-cn/library/system.net.sockets.socketasynceventargs.aspx

具体还需要自己实现

这个SocketAsyncEventArgs是微软对iocp的封装,可以实现高并发socket

收获园豆:20
海之殇 | 园豆:500 (菜鸟二级) | 2018-05-10 14:40
0

当你客户端连接到300的时候,统计一下有多少个线程在跑RecMsg?另外socket用完要调用close释放

收获园豆:20
雙孖星 | 园豆:146 (初学一级) | 2018-05-11 16:14
0

可以考虑用线程池管理你的线程 这样会好一点 如果要对UI操作建议用Invoke

我丫的是条鱼 | 园豆:240 (菜鸟二级) | 2018-05-29 11:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册