求解c# socket 500长连接效率问题!!

kekezhu0000 2016-12-30 09:11:23
大题情况是这样的,为了做企业应用软件便于开发,cline端传入的是DATASET, 然后对DATASET 进行序列化操作在进行数据分包,数据包大小为1M。
server 端是异步结构,代码如下,后面的调用GetDBMessageClass GetDBM = new GetDBMessageClass(csc);包括了数据包拼接,反序列化,还有就是为了方便添加后台数据库处理服务用了反射,因为数据库读写影响效率我在后台的数据库读写改为文件写入。用了10台i5台式机做CLINE,每台上上面打开50个长连接,结果看文件操作,效率为每秒仅仅1条记录,
服务器配置 :IBM System x3850 X5
我想知道我做的SERVER 速度是不是真的很慢!!!!很纠结,看到好多帖子,少则上千,多则过万,求解!!!!
对了如果改用 完成端口(IOCP) 是不是效率比较快,应为还有过IOCP 不敢冒险,请大侠们指教!!!!!




...全文
278 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
kekezhu0000 2016-12-30
  • 打赏
  • 举报
回复
理解较慢,正在认真拜读您的回复
  • 打赏
  • 举报
回复
我只是说一下最顶层的问题。由于顶层的同步、异步、并发方面的问题,你的底层的问题就会堆积起来。 例如文件 I/O 操作是非常耗时间的。数据库系统打开一次数据库文件,只需要一次查找文件目录进行 I/O。而你如果自己写的程序,则可能需要几百万次额外的这类 I/O 。再比如写日志肯定也是耗时间的。等等。 当顶层的流程不是真正异步多线程的(虽然你用了异步的语法,但是流程拖沓,实际上是顺序执行的),那么这些底层耗时的操作就顺序排队了,阻塞现象就更严重了。
  • 打赏
  • 举报
回复
TcpListener/TcpClient 异步编程处理本身就是 IOCP机制!不知道你所谓的 IOCP 是指什么? 不过你的主要问题跟 IOCP无关。你还是应该找到自己的异步处理的流程错误。例如(随便说2条) 1. 一旦EndAccept就应该立刻BeginAccept,一旦EndReceive就应该立刻BeginReceive,而不是等到顺序处理完费时的操作之后才开始 BeginXXXX。像你这种顺序处理,还要异步干什么?纯粹是假异步,用着异步的语法来执行同步顺序的操作。 在当前命令没有处理完毕之前,下一个消息(下一个 Accept 以及下一个 read_Callback)就应该可以异步并发地被执行。而你似乎是没有能力搞定并发流程,所以用异步语法,写了一个同步顺序的程序出来。 2. 在你的顺序处理的过程中的细节,还是有许多东西是不需要同步的。例如写日志应该异步并发地使用(系统线程池的)子线程来处理,而不应该插在顺序过程中处理。 你的处理过程过于顺序化,实际上也就拖延了执行 read_Callback 的 I/O 线程。在 64 系统的 .net 程序系统线程池,I/O 线程最多只有1024个,而 worker 线程则可以有 3万多个。你应该让 read_Callback 方法瞬间执行完毕(几毫秒),尽快释放I/O线程,把耗时的操作分为它注册的几个子任务去注册给系统线程池(Worker线程去并发操作),而不是堆在 read_Callback 中去执行。
kekezhu0000 2016-12-30
  • 打赏
  • 举报
回复
服务器配置:
kekezhu0000 2016-12-30
  • 打赏
  • 举报
回复
我帖的服务端代码 “sp1234” 您受累给看看是不是有问题
kekezhu0000 2016-12-30
  • 打赏
  • 举报
回复
是不是 序列化 反序列化 再加上 反射 影响了效率
  • 打赏
  • 举报
回复
服务器每秒处理1万条才是正常的速度!
kekezhu0000 2016-12-30
  • 打赏
  • 举报
回复
  /// 启动服务的方法
        /// </summary>
        public void strartServer() {
            _packageCount = Convert.ToInt64(FileRead.packagePath().Trim());
            _sessionTable = new Hashtable();
            IPAddress local = IPAddress.Parse(FileRead.ServerPath().Split('@')[0].Split(':')[1].Trim());
            IPEndPoint iep = new IPEndPoint(local, Convert.ToInt32(ynSER.FileRead.ServerPath().Split('@')[1].Split(':')[1].Trim()));
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Bind(iep);
            server.Listen(2000);  
            server.BeginAccept(new AsyncCallback(Accept), server);       
        }
        /// <summary>
        /// 异步调用  回调函数
        /// </summary>
        /// <param name="iar"></param>
        public void Accept(IAsyncResult iar)
        {           
            Socket oldserver = null;
            //传入的socket
            oldserver = (Socket)iar.AsyncState;
            //在原始套接字上调用EndAccept方法,返回新的套接字
            //Socket recSocket = oldserver.EndAccept(iar);
            Socket recSocket = null;
            try {
                recSocket = oldserver.EndAccept(iar);
            }catch(Exception eee){
                return;
            }
            try
            {
                if (_sessionTable.Count>2000)
                {
                    //_sessionTable.Add(_sessionTable.Count, recSocket);
                    //超过最大连接数  告诉客户端服务器已满
                    byte[] isFull = Encoding.UTF8.GetBytes("0");
                    recSocket.Send(isFull);
                    LogClass.WriteLog("Error", "socket:" + recSocket.RemoteEndPoint, "满了!!!!" + recSocket.RemoteEndPoint.ToString().Split(':')[1].ToString());
                    clineSocketClass csc = new clineSocketClass();
                    csc.socke = recSocket;
                    csc.byt = new byte[_packageCount];
                    csc.pf = new NewPackageFile();
                    csc._BYTE_REC = new Hashtable();
                    csc.OK_STR_HS = new Hashtable();
                    csc.socke.BeginReceive(csc.byt, 0, csc.byt.Length, SocketFlags.None, new AsyncCallback(read_Callback), csc);

                    server.BeginAccept(new AsyncCallback(Accept), server);                                  
                }else{
                       byte[] isFull = Encoding.UTF8.GetBytes("1");
                       recSocket.Send(isFull);

                       lock (_sessionTable)
                       {
                           _sessionTable.Add(recSocket.Handle, recSocket);
                       }                
                      if (event_Conn != null)
                     {
                        clineSocketEnentArgs socketConn = new clineSocketEnentArgs();
                        socketConn.Clin_message = "连接:[" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss").ToString() + "]" + recSocket.RemoteEndPoint.ToString();
                        event_Conn(this, socketConn);
                     }                 
                      //多线程传递当前并发数量
                      if (event_ConnectionCount!=null)
                      {
                          NowConnectionCountEnentArgs NowConnectionCount = new NowConnectionCountEnentArgs();
                          NowConnectionCount.NowConnectionCount1_message = _sessionTable.Count.ToString();
                          event_ConnectionCount(this, NowConnectionCount);
                      }
                    clineSocketClass csc = new clineSocketClass();
                    csc.socke = recSocket;
                    csc.byt = new byte[_packageCount];
                    csc.pf = new NewPackageFile();
                    csc._BYTE_REC = new Hashtable();
                    csc.OK_STR_HS = new Hashtable();
                    csc.socke.BeginReceive(csc.byt, 0, csc.byt.Length, SocketFlags.None, new AsyncCallback(read_Callback), csc);            
                    server.BeginAccept(new AsyncCallback(Accept), server); 
                    }
            }
            catch (SocketException e)
            {
                if (event_excmessage != null)
                {
                    ECXEEventArgs eea = new ECXEEventArgs();
                    eea.EXC_message1 = string.Format("【异常】[" + recSocket.RemoteEndPoint.ToString() + "]:" + e.ToString());
                    event_excmessage(this, eea);
                }
                oldserver.Close();
            }
        }
        /// <summary>
        /// 接收数据的回调函数
        /// </summary>
        /// <param name="iar"></param>
        public void read_Callback(IAsyncResult iar)
        {
            clineSocketClass csc = (clineSocketClass)iar.AsyncState;
           // LogClass.WriteLog("Error", "huidiao:", "huidiao");
            try
            {
                int recv = csc.socke.EndReceive(iar);
                csc.HDcount++;
                csc.cut_pg_count = this._packageCount;
                if (recv!=0) { 
                //处理多余的字节数组问题
                byte[] Middle_Byte = new byte[recv];           
                /**
                 * 当接受的数据小于socket缓
                 * 存的时候将多余的空位删除掉,
                 * 否则在数据包的解析过程中
                 * 会出现各种问题
                 */
                 //Array.Copy(源数据, 源数据开始复制处索引, 接收数据, 接收数据开始处索引, 复制多少个数据);
                 Array.Copy(csc.byt, 0, Middle_Byte, 0, recv);
                // string isgo = "yes";
                if (csc.pf.teturn_byte_message == null)
                 {
                     csc.pf.GetActualString("", Middle_Byte);
                     csc.ServerName = csc.pf.SN;
                     if (csc.pf.teturn_byte_message!=null)
                     {
                         if (csc.pf.ZC == csc.pf.teturn_byte_message.Length)
                         {
                             // LogClass.WriteLog("Error", "数据包解析完毕", "数据包解析完毕");
                             GetDBMessageClass GetDBM = new GetDBMessageClass(csc);
                            // LogClass.WriteLog("Error", "【" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ffff").ToString() + "】", "插入异常" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss").ToString().Replace('-', ' ').Replace(':', ' '));
                             csc.pf = new NewPackageFile();
                             lock (_sessionTable)
                             {
                                 _sessionTable.Remove(csc.socke.Handle);
                                 _CLZSCount++;
                             }
                             //多线程传递当前并发数量
                             if (event_ConnectionCount != null)
                             {
                                 NowConnectionCountEnentArgs NowConnectionCount = new NowConnectionCountEnentArgs();
                                 NowConnectionCount.NowConnectionCount1_message = _sessionTable.Count.ToString();
                                 event_ConnectionCount(this, NowConnectionCount);
                             }
                         }
                    }  
                 }
                 else {

                     if (csc.pf.ZC != csc.pf.teturn_byte_message.Length)
                     {
                         csc.pf.GetActualString("", Middle_Byte);
                        // LogClass.WriteLog("Error", "数据包解析", "数据包解析");
                         if (csc.pf.ZC == csc.pf.teturn_byte_message.Length)
                         {
                             //LogClass.WriteLog("Error", "数据包解析完毕", "数据包解析完毕" + csc.socke.Handle);
                              GetDBMessageClass GetDBM = new GetDBMessageClass(csc);
                            // LogClass.WriteLog("Error", "【" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ffff").ToString() + "】", "插入异常" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ffff").ToString().Replace('-', ' ').Replace(':', ' '));
                              csc.pf = new NewPackageFile();
                             _sessionTable.Remove(csc.socke.Handle);
                             lock (_sessionTable)
                             {
                                 _sessionTable.Remove(csc.socke.Handle);
                                 _CLZSCount++;
                             }
                             //多线程传递当前并发数量
                             if (event_ConnectionCount != null)
                             {
                                 NowConnectionCountEnentArgs NowConnectionCount = new NowConnectionCountEnentArgs();
                                 NowConnectionCount.NowConnectionCount1_message = _sessionTable.Count.ToString();
                                 event_ConnectionCount(this, NowConnectionCount);
                             }
                         }
                        
                     }
                 }

                    //清空系统缓存
                csc.byt = new byte[_packageCount];  
                    //执行回调函数的时候已经进行了数据的接收
                    csc.socke.BeginReceive(csc.byt, 0, csc.byt.Length, SocketFlags.None, new AsyncCallback(read_Callback), csc);
                }
            }
            catch (SocketException e)
            {
                if (event_excmessage != null)
                {
                    ECXEEventArgs eea = new ECXEEventArgs();
                    eea.EXC_message1 = string.Format("【--异常--】[" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss:ffff").ToString() + "]:" + e.ToString());
                    event_excmessage(this, eea);
                }
            }
        }

110,538

社区成员

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

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

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