Exemple #1
0
        /// <summary>
        /// 压缩文件,参数是输入文件路径和输出文件路径。
        /// </summary>
        /// <param name="sourceFile">输入文件路径</param>
        /// <param name="destinationFile">输出文件路径</param>
        public static void CompressFile(string sourceFile, string destinationFile)
        {
            // make sure the source file is there
            if (File.Exists(sourceFile) == false)
            {
                throw new FileNotFoundException();
            }

            // Create the streams and byte arrays needed
            byte[]     buffer            = null;
            FileStream sourceStream      = null;
            FileStream destinationStream = null;
            GZipStream compressedStream  = null;

            try
            {
                // Read the bytes from the source file into a byte array
                sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);

                // Read the source stream values into the buffer
                buffer = new byte[sourceStream.Length];
                int checkCounter = sourceStream.Read(buffer, 0, buffer.Length);

                if (checkCounter != buffer.Length)
                {
                    throw new ApplicationException();
                }

                // Open the FileStream to write to
                destinationStream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write);

                // Create a compression stream pointing to the destiantion stream
                compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true);

                // Now write the compressed data to the destination file
                compressedStream.Write(buffer, 0, buffer.Length);
            }
            catch (ApplicationException e)
            {
                DxDebug.LogWarning("GZip.CompressFile():异常:" + e.Message);
            }
            finally
            {
                // Make sure we allways close all streams
                if (sourceStream != null)
                {
                    sourceStream.Close();
                }

                if (compressedStream != null)
                {
                    compressedStream.Close();
                }

                if (destinationStream != null)
                {
                    destinationStream.Close();
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// 压缩一段数据,这个数据长度不能过大,最好在1M以内
        /// </summary>
        /// <param name="sourceData">用于存储压缩字节的数组</param>
        /// <param name="offset">数组中开始读取的位置</param>
        /// <param name="count">压缩的字节数</param>
        /// <returns></returns>
        public static byte[] CompressBytes(byte[] sourceData, int offset, int count)
        {
            if (sourceData == null)
            {
                return(null);
            }

            MemoryStream destinationStream = new MemoryStream();
            GZipStream   compressedStream  = new GZipStream(destinationStream, CompressionMode.Compress);

            try
            {
                compressedStream.Write(sourceData, offset, count);

                compressedStream.Close();

                byte[] CompressedData = destinationStream.ToArray();
                destinationStream.Close();
                return(CompressedData);
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("GZip.CompressBytes():异常:" + e.Message);
            }
            finally
            {
                // Make sure we allways close all streams
                if (destinationStream != null)
                {
                    destinationStream.Close();
                }
            }
            return(null);
        }
Exemple #3
0
 private void Dispose(bool disposing)
 {
     if (disposed)
     {
         return;
     }
     if (disposing)
     {
         // 清理托管资源
     }
     // 清理非托管资源
     try
     {
         if (_timer != null)
         {
             _timer.Dispose();
         }
     }
     catch (Exception e)
     {
         DxDebug.LogWarning("ServerTimer.Dispose():异常_timer.Dispose()" + e.Message);
     }
     //让类型知道自己已经被释放
     disposed = true;
 }
Exemple #4
0
        /// <summary>
        /// 定时器函数
        /// </summary>
        /// <param name="state"></param>
        private void OnTimerTick(object state)
        {
            try
            {
                //如果自动心跳包功能打开了
                if (Config.IsAutoHeartbeat == true)
                {
                    CheckOffLineAndSend();
                }

                //执行事件
                if (EventOnTimer != null)
                {
                    try
                    {
                        EventOnTimer();
                    }
                    catch (Exception e)
                    {
                        DxDebug.LogWarning("ServerTimer.OnTimerTick():执行EventOnTimer事件异常:" + e.Message);;
                    }
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("ServerTimer.OnTimerTick():异常:" + e.Message);
            }
        }
Exemple #5
0
        /// <summary>
        /// 添加一个token
        /// </summary>
        /// <param name="token"></param>
        internal Token AddToken(Token token)
        {
            lock (this._lockDict)
            {
                token.ID = _curID;
                _dictToken.Add(token.ID, token);
                //递增ID计数,额,不过上面已经加锁了
                Interlocked.Increment(ref _curID);

                _isDictEqualArr = false; //标记当前字典和列表已经不一致了
            }
            if (EventAddToken != null)   //事件
            {
                try
                {
                    EventAddToken(token.ID);
                }
                catch (Exception e)
                {
                    DxDebug.LogWarning("TokenManager.AddToken():执行事件EventAddToken异常!" + e.Message);
                }
            }
            DxDebug.LogConsole(String.Format("TokenManager.AddToken():添加了一个客户端. 当前服务器上有{0}个客户端; ip:{1}", _dictToken.Count, token.IP));
            return(token);
        }
Exemple #6
0
        /// <summary>
        /// 开始接受客户端的Accept
        /// </summary>
        private void StartAccept(SocketAsyncEventArgs eArg)
        {
            //lock (_lockAccept)//这个加锁没有解决问题
            //{
            try
            {
                if (eArg == null)
                {
                    eArg            = new SocketAsyncEventArgs();
                    eArg.Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted);
                }

                eArg.AcceptSocket = null;   // 必须要先清掉Socket

                DxDebug.LogConsole("SocketListener.StartAccept():服务器开始接收认证!");
                //开始异步接收认证
                if (!_listenSocket.AcceptAsync(eArg))
                {
                    this.ProcessAccept(eArg);
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("SocketListener.StartAccept():异常:" + e.Message);
                // throw;
            }
            //}
        }
Exemple #7
0
        /// <summary>
        /// 添加一个工作任务到消息队列,提供给这些线程来处理
        /// </summary>
        /// <param name="msg"></param>
        public void AddMessage(IWorkMsg msg)
        {
            try
            {
                if (_msgQueue.EnqueueMaxLimit(msg))
                {
                    if (_curSemCount < 1)//如果当前的信号量剩余不多的时候
                    {
                        Interlocked.Increment(ref _curSemCount);
                        _msgSemaphore.Release();// 释放信号量
                    }
                }
                else
                {
                    DxDebug.LogWarning("WorkThread.AddMessage():大于工作线程的能力了,丢弃了一条消息!");
                }

                if (_msgQueuePeakLength < _msgQueue.Count)
                {
                    _msgQueuePeakLength = _msgQueue.Count;//记录当前的峰值长度
                }
            }
            catch (SemaphoreFullException)
            {
                DxDebug.LogError("WorkThread.AddMessage():大于工作线程的能力了:");

                throw;
            }
            catch (Exception e)
            {
                DxDebug.LogError("WorkThread.AddMessage():异常:" + e.Message);
                throw;
            }
        }
Exemple #8
0
        /// <summary>
        /// 开始一个接收
        /// </summary>
        private void PrepareReceive()
        {
            try
            {
                //这里是需要的,否则在断线之后仍然可能不停的接收
                if (!_clientSocket.Connected) //如果当前没有连接上,就不接收了
                {
                    return;
                }

#if !NEW_EVENT_AEGS
                _receiveArgs.SetBuffer(_receiveBuffer, 0, _receiveBuffer.Length);
#else
                SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
                receiveArgs.UserToken      = this.clientSocket;
                receiveArgs.RemoteEndPoint = this.hostEndPoint;
                byte[] receiveBuffer = new byte[2048]; //接收buffer大小为2048;
                receiveArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
                receiveArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnReceive);
#endif
                if (!_clientSocket.ReceiveAsync(_receiveArgs))//开始接收
                {
                    ProcessReceive(this, _receiveArgs);
                }
                _receTime.WaitStart();
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("SocketClient.PrepareReceive() 开始异步接收错误:" + e.Message);
                //这里捕获过的异常有:
                // Thread creation failed.
            }
        }
Exemple #9
0
        /// <summary>
        /// 删除一个token,会自动关闭连接。会产生事件
        /// </summary>
        /// <param name="id">根据ID删除已个Token</param>
        public void DeleteToken(int id)
        {
            CloseToken(id, TokenErrorType.UserDelete);//先关闭
            lock (this._lockDict)
            {
                if (_dictToken.ContainsKey(id))
                {
                    _dictToken.Remove(id);

                    _isDictEqualArr = false;//标记当前字典和数组已经不一致了
                }
                else
                {
                    return;
                }
            }
            if (EventDeleteToken != null)//事件
            {
                try
                {
                    EventDeleteToken(id, TokenErrorType.UserDelete);//这个是外部的调用删除
                }
                catch (Exception e)
                {
                    DxDebug.LogWarning("TokenManager.DeleteToken():执行事件EventDeleteToken异常!" + e.Message);
                }
            }

            DxDebug.LogConsole(String.Format("TokenManager.DeleteToken():关闭了一个客户端. 还有{0}个客户端,原因{1}", _dictToken.Count, TokenErrorType.UserDelete.ToString()));
        }
Exemple #10
0
        /// <summary>
        /// 发生错误后就关闭连接
        /// </summary>
        /// <param name="e"></param>
        private void ProcessError(SocketAsyncEventArgs e)
        {
            DxDebug.LogWarning("SocketClient.ProcessError():进入了ProcessError.  ErroType:" + e.SocketError); //显示下接收的信息
            Socket s = e.UserToken as Socket;                                                              //使用传递的Token

            if (s.Connected)
            {
                try
                {
                    DxDebug.LogConsole("SocketClient.ProcessError():调用Shutdown()关闭连接");
                    s.Shutdown(SocketShutdown.Both);
                }
                catch (Exception ex)
                {
                    DxDebug.LogWarning("SocketClient.ProcessError() :Shutdown()异常 " + ex.Message);
                }
                finally
                {
                    if (s.Connected)
                    {
                        s.Close();
                        DxDebug.LogWarning("SocketClient.ProcessError() :调用Close()关闭了连接");//这里是否必须要关闭待定
                    }
                }
            }
            //产生错误事件,这是一个很重要的事件,处理服务器连接断开等
            if (EventError != null)
            {
                EventError();
            }
        }
Exemple #11
0
 private void DoStart(NetWorkMsg msg)
 {
     try
     {
         DxDebug.LogConsole("DNServer.DoStart():工作线程开始执行DoStart()...");
         if (_socketListener != null)
         {
             DxDebug.Log(" DNServer.DoStart():_socketListener.Dispose();");
             _socketListener.Dispose();
         }
         DxDebug.Log("DNServer.DoStart():_socketListener = new SocketListener(CONNECTIONS_BUFFER_SIZE);");
         _socketListener = new SocketListener(this, CONNECTIONS_BUFFER_SIZE);
         DxDebug.Log("DNServer.DoStart():_socketListener.EventAccept += OnAccept;");
         _socketListener.EventAccept  += OnAccept;
         _socketListener.EventReceive += OnReceive;
         _socketListener.EventSend    += OnSend;
         _socketListener.EventError   += OnTokenError;
         DxDebug.Log("DNServer.DoStart(): _socketListener.Start(" + _port + ");");
         _socketListener.Start(msg.text1, _port);
         DxDebug.LogConsole("DNServer.DoStart()执行完毕!");
     }
     catch (Exception e)
     {
         DxDebug.LogWarning("DNServer.DoStart():异常 " + e.Message);
     }
 }
Exemple #12
0
        private void ProcessConnect(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                //这种回调是新开了一个线程执行的
                _areConnectDone.Set();

                if (IsConnected)
                {
                    PrepareReceive(); //自动开始一个接收
                }
                else
                {
                    DxDebug.LogWarning("SocketClient.ProcessConnect():没能自动开始接收 IsConnected = " + IsConnected);
                }
                if (EventConnect != null) //执行事件
                {
                    EventConnect();
                }
            }
            catch (Exception ex)
            {
                DxDebug.LogWarning("SocketClient.ProcessConnect():异常:" + ex.Message);
            }
        }
Exemple #13
0
        private void DoReceive()
        {
            try
            {
                //不再做心跳包处理,直接发出事件
                LastMsgReceTickTime = DateTime.Now.Ticks;
                //接收数据事件
                if (EventReceData != null)
                {
                    try
                    {
                        EventReceData(this);//发出事件:接收到了数据
                    }
                    catch (Exception e)
                    {
                        DxDebug.LogWarning("DNClient.DoReceive():执行外部事件EventReceData 异常: " + e.Message);
                    }
                }

                //DxDebug.Log("-----------数据解包完成,数据条数:  " + findPacketResult.data.Length);
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.DoReceive():异常: " + e.Message);
            }
        }
Exemple #14
0
 /// <summary>
 /// 线程函数,向所有Token发送他们的待发送数据
 /// </summary>
 /// <param name="msg"></param>
 private void DoSendAll(NetWorkMsg msg)
 {
     try
     {
         Token[] tokens = TokenManager.GetInstance().GetAllToken();
         if (tokens == null)
         {
             return;
         }
         for (int i = 0; i < tokens.Length; i++)
         {
             Token token = tokens[i];
             //DxDebug.Log("DoSend : ID号 " + token.ID + "  当前的SendingCount  " + token.SendingCount);
             if (token.SendingCount < MAX_TOKEN_SENDING_COUNT)
             {
                 int    msgCount = token.SendQueueCount;
                 byte[] data     = token.PackSendData(_packet); //打包发送
                 if (data != null)
                 {
                     Interlocked.Add(ref Status.CountSend, msgCount);         //状态统计发送递增
                     Interlocked.Add(ref Status.CountSendBytes, data.Length); //状态统计递增发送数据长度
                     _socketListener.Send(token, data);
                 }
             }
             else //如果当前正在发送,那么这次发送完成之后,会自动的开始下一次发送:OnSend()函数
             {
             }
         }
     }
     catch (Exception e)
     {
         DxDebug.LogWarning("DNServer.DoSendAll():异常 " + e.Message);
     }
 }
Exemple #15
0
        /// <summary>
        /// 发送一条数据
        /// </summary>
        /// <param name="data">要发送的整个数据</param>
        public void Send(byte[] data)
        {
            if (data == null)
            {
                DxDebug.LogWarning("DNClient.Send():要发送的数据为null!");
            }

            try
            {
                _packet2.AddSend(data, 0, data.Length);//添加这条消息到打包器

                NetWorkMsg msg = _msgPool.Dequeue();
                if (msg == null)
                {
                    msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Send);
                }
                else
                {
                    msg.Reset(NetWorkMsg.Tpye.C_Send);
                }
                AddMessage(msg);
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.Send():异常 " + e.Message);
            }
        }
Exemple #16
0
        /// <summary>
        /// 发送一条数据,有起始和长度控制
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <param name="offset">数据的起始位置</param>
        /// <param name="count">数据的长度</param>
        public void Send(byte[] data, int offset, int count)
        {
            if (data == null)
            {
                DxDebug.LogWarning("DNClient.Send(data,offset,count):要发送的数据为null!");
            }
            try
            {
                _packet2.AddSend(data, offset, count);//添加这条消息到打包器

                //进行数据的预打包,然后不拷贝
                NetWorkMsg msg = _msgPool.Dequeue();
                if (msg == null)
                {
                    msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Send);
                }
                else
                {
                    msg.Reset(NetWorkMsg.Tpye.C_Send);
                }
                AddMessage(msg);
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.Send(p1,p2,p3):异常 " + e.Message);
            }
        }
Exemple #17
0
        /// <summary>
        /// 由Socket开始一个异步发送
        /// </summary>
        /// <param name="token"></param>
        /// <param name="data"></param>
        internal void Send(Token token, byte[] data)
        {
            int errorCount = 0;

            try
            {
                if (token.disposed == false)       //如果这个token已经被释放,那就不要再发送了
                {
                    token.IncrementSendingCount(); //计数递增:这里需要及早标记,否则多线程调用SocketAsyncEventArgs会异常。

                    SocketAsyncEventArgs sendEventArgs = token.SendArgs;
                    sendEventArgs.SetBuffer(data, 0, data.Length);

                    //这里这个有可能会出现异常:"现在已经正在使用此 SocketAsyncEventArgs 实例进行异步套接字操作。
                    //所以这句可能要加锁
                    if (!token.socket.SendAsync(sendEventArgs))  //开始发送  ,这里作异常处理()
                    {
                        OnCompletedProcessSend(this, sendEventArgs);
                    }
                }
            }
            catch (Exception e)
            {
                errorCount++;
                DxDebug.LogWarning("SocketListener.Send():异常:" + e.Message);
                token.DecrementSendingCount();//直接异常了就去掉这个计数递减
                if (errorCount <= 2)
                {
                    DxDebug.LogConsole("SocketListener.Send()尝试自动重试!errorCount=" + errorCount);
                    Send(token, data);
                }
            }
        }
Exemple #18
0
        /// <summary>
        /// 这个函数只绑定了acceptEventArg
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnIOCompleted(object sender, SocketAsyncEventArgs e)
        {
            //lock (_lockAccept)
            //{
            switch (e.LastOperation)
            {
            case SocketAsyncOperation.Accept:
                //当关闭Socket的时候,如果没有注销事件,那么也会进入这里,所以作了一个判断(同时注销事件也完善了)
                if (e.SocketError != SocketError.OperationAborted)
                {
                    this.ProcessAccept(e);
                }
                break;

            /*  case SocketAsyncOperation.Receive:
             *    this.ProcessReceive(this,e);
             *    break;
             *
             * case SocketAsyncOperation.Send:
             *    this.ProcessSend(this,e);
             *    break;*/
            default:
                DxDebug.LogWarning("SocketListener:OnIOCompleted(): 进入了未预料的switch分支!");
                break;
            }
            //}
        }
Exemple #19
0
        private void DoClose()
        {
            try
            {
                IsInited = false;
                DxDebug.LogConsole("DNClient.DoClose():开始释放资源 ");
                _disposed = true;

                // 清理托管资源
                _msgQueue.Clear();
                _msgPool.Clear();

                _msgQueue = null;
                _msgPool  = null;

                // 清理非托管资源
                _msgSemaphore.Close();
                _msgSemaphore = null;
                Interlocked.Exchange(ref _curSemCount, 0);

                if (_socketClient != null)
                {
                    _socketClient.Dispose();
                    _socketClient = null;
                }

                IsConnecting = false;
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.DoClose():异常: " + e.Message);
            }
        }
Exemple #20
0
 private void ProcessReceive(object sender, SocketAsyncEventArgs e)
 {
     _receTime.WorkStart();
     try
     {
         //_areReceiveDone.Set();//设置信号量(但是目前压根没用到)
         if (e.SocketError != SocketError.Success)
         {
             this.ProcessError(e);
         }
         if (e.BytesTransferred > 0) //有可能会出现接收到的数据长度为0的情形,如当服务器关闭连接的时候
         {
             //写入当前接收的数据
             int msgCount = _packet2.AddRece(e.Buffer, e.Offset, e.BytesTransferred);
             //如果确实收到了一条消息
             if (msgCount > 0 && EventReceive != null) //执行事件
             {
                 EventReceive();
             }
         }
         else
         {
             this.ProcessError(e);
         }
         PrepareReceive(); //开始下一个接收
     }
     catch (Exception ex)
     {
         DxDebug.LogWarning("SocketClient:ProcessReceive():" + ex.Message);
     }
 }
Exemple #21
0
        private void DoWork()
        {
            DxDebug.LogConsole("DNServer.DoWork():服务器线程启动!");
            while (true)
            {
                _msgSemaphore.WaitOne();
                Interlocked.Decrement(ref _curSemCount);
                while (true)
                {
                    _cpuTime.WorkStart(); //时间分析计时
#if Multitask
                    NetWorkMsg msg1 = _msgQueue.Dequeue();
                    NetWorkMsg msg2 = _msgQueue.Dequeue();
                    if (msg1 == null && msg2 == null)
                    {
                        break;
                    }
                    else if (msg1 != null && msg2 != null)//取到了两条消息
                    {
                        //再消耗一条信号量
                        //_msgSemaphore.WaitOne();
                        Interlocked.Decrement(ref _curSemCount);
                        Parallel.Invoke(delegate() { ProcessMsg(msg1); }, delegate() { ProcessMsg(msg2); });
                    }
                    else if (msg1 != null && msg2 == null)
                    {
                        //只有一条消息,就直接执行
                        ProcessMsg(msg1);
                    }
                    else if (msg1 == null && msg2 != null)
                    {
                        //只有一条消息,就直接执行
                        ProcessMsg(msg2);
                    }
#else
                    NetWorkMsg msg = _msgQueue.Dequeue();
                    if (msg == null) //直到消息取尽之前都不停的处理
                    {
                        break;
                    }
                    float waitTime = (DateTime.Now.Ticks - msg.timeTickCreat) / 10000;//毫秒
                    if (waitTime > _warringWaitTime)
                    {
                        _warringWaitTime += 500;
                        DxDebug.LogWarning("DNServer.DoWork():NetWorkMsg等待处理时间过长!waitTime:" + waitTime);
                    }
                    else if ((_warringWaitTime - waitTime) > 500)
                    {
                        _warringWaitTime -= 500;
                    }

                    ProcessMsg(msg);
#endif
                    _cpuTime.WaitStart(); //时间分析计时
                }
            }
        }
Exemple #22
0
 /// <summary>
 /// 构造函数
 /// </summary>
 public TokenManager()
 {
     if (_instance != null)
     {
         DxDebug.LogWarning("TokenManager是个单例,被多次调用构造函数");
         //this.Dispose();
         //_instance = null;
     }
 }
Exemple #23
0
        /// <summary>
        /// 定时器函数
        /// </summary>
        /// <param name="state"></param>
        private void OnTimerTick(object state)
        {
            DNClient client = DNClient.GetInstance();

            if (Config.IsAutoHeartbeat && client.IsConnected)
            {
                float time = (DateTime.Now.Ticks - client.LastMsgSendTickTime) / 10000;
                if (time > Config.HeartBeatSendTime)//如果时间已经超过了那么就发送心跳包
                {
                    //发送一次心跳包
                    SendHeartBeat();
                }
            }

            if (Config.IsAutoHeartbeat && client.IsConnected)
            {
                //如果15s没有收到心跳包
                float time = (DateTime.Now.Ticks - client.LastMsgReceTickTime) / 10000;
                if (time > Config.HeartBeatCheckTime)
                {
                    DxDebug.LogWarning("ClientTimer.OnTimerTick():长时间没有收到心跳包,判断可能已经掉线!");
                    client.Disconnect();//关闭连接
                }
            }

            //执行事件
            if (EventOnTimer != null)
            {
                try
                {
                    EventOnTimer();
                }
                catch (Exception e)
                {
                    DxDebug.LogWarning("ClientTimer.OnTimerTick():执行EventOnTimer事件异常:" + e.Message);
                }
            }

            //执行3秒事件
            if (EventOnTimer3S != null)
            {
                _count3S += KICK_TIME;
                if (_count3S >= 3 * 1000) //20秒
                {
                    _count3S = 0;
                    try
                    {
                        EventOnTimer3S();
                    }
                    catch (Exception e)
                    {
                        DxDebug.LogWarning("ClientTimer.OnTimerTick():执行EventOnTimer3S事件异常:" + e.Message);;
                    }
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// 解包当前已经接收到的原始数据,结果存放进了已接收消息队列, 返回true如果接收到了消息.
        /// </summary>
        /// <param name="packeter"> 打包方法. </param>
        /// <param name="length">   [out] 接收到数据长度. </param>
        ///
        /// <returns> 解包出来的消息条数(注意不是长度). </returns>
        internal int UnpackReceiveData(IPacket packeter, out int length)
        {
            lock (this._lockReserveData)
            {
                //拼接所有的已接受数据
                byte[] alldata = _reserveQueuePacked.GetDataOnce(_reserveData);
                _reserveData = null;//清空已经无用的_reserveData
                if (alldata == null)
                {
                    length = 0; //长度为0
                    //这个情形在客户端狂发速度过快的时候容易出现,但是不影响接收,所以去掉这个日志
                    //DxDebug.LogWarning("Token.UnpackReceiveData(): alldata为null!");
                    return(0);
                }
                length = alldata.Length;                                             //传出这个数据长度
                FindPacketResult findPacketResult = packeter.FindPacket(alldata, 0); //解包
                _reserveData = findPacketResult.reserveData;                         //更新reserveData
                if (findPacketResult.dataArr != null)                                //将结果加入队列
                {
                    //记录下一共找到的有效消息条数
                    int msgCount = findPacketResult.dataArr.Length;

                    for (int i = 0; i < findPacketResult.dataArr.Length; i++)//结果是一个消息数组
                    {
                        byte[] data = findPacketResult.dataArr[i];
                        if (data == null)
                        {
                            //这里是否会频繁发生?
                            DxDebug.LogWarning("Token.UnpackReceiveData(): 结果中的data为null!");
                            break;
                        }
                        //如果不是心跳包才加入接收消息队列
                        if (!Config.CompareHeartBeat(findPacketResult.dataArr[i]))//Config中的静态函数判断
                        {
                            if (!_receiveQueue.EnqueueMaxLimit(findPacketResult.dataArr[i]))
                            {
                                DxDebug.LogWarning("Token.UnpackReceiveData():接收已解包的数据队列 丢弃了一段数据");
                            }
                        }
                        else
                        {
                            DxDebug.LogFileOnly("Token.UnpackReceiveData():接收到了心跳包 TokenID:" + this.ID);
                        }
                    }
                    LastMsgReceTickTime = DateTime.Now.Ticks; //记录最近一次接收到消息的时间
                    //DxDebug.Log("某个token接收到了 " + findPacketResult.data.Length + "条消息");

                    return(msgCount);
                }
                else
                {
                    DxDebug.LogWarning("Token.UnpackReceiveData():接收到数据,经过FindPacket(),但是没有找到有效消息!");
                    return(0);
                }
            }
        }
Exemple #25
0
        /// <summary>
        /// 添加一条要发送的消息(未打包的数据),不会自动发送。
        /// 这一个方法会进行数据的预打包
        /// </summary>
        /// <param name="data">要发送的数据</param>
        /// <param name="index">数据起始</param>
        /// <param name="length">数据长度</param>
        public void AddSendData(byte[] data, int index, int length)
        {
            IPacket packet = DNServer.GetInstance().Packet;

            //进行预打包然后加入到队列
            if (!_sendQueue.EnqueueMaxLimit(packet.PrePack(data, index, length)))
            {
                DxDebug.LogWarning("Token.AddSendData():要发送的数据队列 丢弃了一段数据");
            }
        }
Exemple #26
0
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            IsInited = false;

            try
            {   //最先去把线程关了
                if (_workThread != null && _workThread.IsAlive)
                {
                    DxDebug.LogConsole("DNClient.Dispose():_workThread.Abort()线程中断!");
                    _workThread.Abort();
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.Dispose(): _workThread.Abort()异常" + e.Message);
            }
            finally
            {
                _workThread = null;
            }

            try
            {
                if (disposing)
                {
                    // 清理托管资源
                    _msgQueue.Clear();
                    _msgPool.Clear();

                    _msgQueue = null;
                    _msgPool  = null;
                }
                // 清理非托管资源
                _packet2.Clear();
                _msgSemaphore.Close();
                _msgSemaphore = null;
                if (_socketClient != null)
                {
                    _socketClient.Dispose();
                    _socketClient = null;
                }
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("DNClient.Dispose():释放异常" + e.Message);
            }
            //让类型知道自己已经被释放
            _disposed = true;

            IsConnecting = false;
        }
Exemple #27
0
        /// <summary>
        /// 连接服务器,输入IP和端口号。会强制重新初始化整个类,这样起到底层重启的作用。
        /// </summary>
        /// <param name="host">主机IP</param>
        /// <param name="port">端口号</param>
        public void Connect(string host, int port)
        {
            try
            {
                DxDebug.LogConsole("DNClient.Connect():连接服务器 主机:" + host + "  端口:" + port);

                //标记正在连接
                IsConnecting = true;

                //if (_disposed)
                //{
                //    DxDebug.LogConsole("DNClient.Connect():这个类对象是被释放状态,重新初始化");
                Init();
                //}

                //进行一次连接的时候,把消息队列清空
                Clear();

                Interlocked.Exchange(ref this._host, host); //给类成员赋值
                Interlocked.Exchange(ref this._port, port); //给类成员赋值

                NetWorkMsg msg = _msgPool.Dequeue();
                if (msg == null)
                {
                    msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Connect);
                }
                else
                {
                    msg.Reset(NetWorkMsg.Tpye.C_Connect);
                }
                AddMessage(msg);

                LastMsgReceTickTime = DateTime.Now.Ticks;
                LastMsgSendTickTime = DateTime.Now.Ticks;
            }
            catch (Exception e)
            {
                IsConnecting = false;//连接失败了
                DxDebug.LogError("DNClient.Connect():异常:" + e.Message);

                if (EventError != null)
                {
                    try
                    {
                        EventError(this, EventType.ConnectError, e);//事件类型:ConnectError
                    }
                    catch (Exception e2)
                    {
                        DxDebug.LogWarning("DNClient.Connect():执行EventError事件异常:" + e2.Message);
                    }
                }

                Dispose();//释放
            }
        }
Exemple #28
0
        /// <summary>
        /// 启动服务器
        /// </summary>
        /// <param name="hostName">服务器的ip</param>
        /// <param name="port">本机的服务器端口</param>
        internal void Start(string hostName, int port)
        {
            try
            {
                _isStarted = false;
                IPAddress address = IPAddress.Any;
                if (hostName == "Any")
                {
                    address = IPAddress.Any;
                }
                else if (Regex.IsMatch(hostName, @"\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}"))
                {
                    byte[] ipadr = new byte[4];

                    MatchCollection ms = Regex.Matches(hostName, @"\d{1,3}");
                    for (int i = 0; i < ms.Count; i++)
                    {
                        ipadr[i] = Convert.ToByte(hostName.Substring(ms[i].Index, ms[i].Length));
                    }
                    address = new IPAddress(ipadr);
                }
                else
                {
                    IPHostEntry host        = Dns.GetHostEntry(hostName);
                    IPAddress[] addressList = host.AddressList;
                    address = addressList[addressList.Length - 1];
                }
                IPEndPoint localEndPoint = new IPEndPoint(address, port);
                DxDebug.LogConsole("SocketListener.Start():尝试启动服务器 " + address + ":" + port);

                //创建一个监听Socket
                this._listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                this._listenSocket.ReceiveBufferSize = this._bufferSize;
                this._listenSocket.SendBufferSize    = this._bufferSize;

                if (localEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    this._listenSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false);
                    this._listenSocket.Bind(new IPEndPoint(IPAddress.IPv6Any, localEndPoint.Port));
                }
                else
                {
                    this._listenSocket.Bind(localEndPoint);
                }
                this._listenSocket.Listen(2); //最大挂起数
                this.StartAccept2();

                _isStarted = true;//服务器启动成功
            }
            catch (Exception e)
            {
                DxDebug.LogWarning("SocketListener.Start():Start函数错误:" + e.Message);
            }
        }
Exemple #29
0
        /// <summary>
        /// 线程的工作函数
        /// </summary>
        private void DoWork()
        {
            DxDebug.LogConsole("WorkThread.DoWork():工作线程启动!");

            while (_isRun)
            {
                IWorkMsg msg = null;
                try
                {
                    //记录线程空闲
                    RecThreadStatus(Thread.CurrentThread.ManagedThreadId, false);

                    _msgSemaphore.WaitOne();
                    Interlocked.Decrement(ref _curSemCount);

                    //记录线程开始工作
                    RecThreadStatus(Thread.CurrentThread.ManagedThreadId, true);

                    while (true)
                    {
                        msg = _msgQueue.Dequeue();
                        if (msg != null)
                        {
                            //递增计数
                            Interlocked.Increment(ref _procMsgCount);
                            try
                            {
                                //取一条消息进行执行
                                msg.DoWork();
                            }
                            catch (Exception e)
                            {
                                DxDebug.LogWarning("WorkThread.DoWork():执行msg异常:" + msg.Name + "异常信息:" + e.Message);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (msg != null)
                    {
                        DxDebug.LogError("WorkThread.DoWork():异常:" + msg.Name + "异常信息:" + e.Message);
                    }
                    else
                    {
                        DxDebug.LogError("WorkThread.DoWork():异常:目前IWorkMsg为null(可能空闲),异常信息:" + e.Message);
                    }
                }
            }
        }
Exemple #30
0
        /// <summary>
        /// 执行异步接收完成处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnCompletedProcessReceive(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                // 如果返回0说明远程端已经关闭了连接,MSDN说明如下:
                // 此属性提供在可接收或发送数据的异步套接字操作传输的字节数。 如果从读取操作返回零,则说明远程端已关闭了连接。
                if (e.BytesTransferred > 0)
                {
                    if (e.SocketError == SocketError.Success)
                    {
                        Token token = e.UserToken as Token;
                        token.SetData(e);

                        /* Socket s = token.socket;
                         * if (s.Available == 0)
                         * {
                         *   if (EventReceive != null)//产生接收事件,通知线程进行解包
                         *   {
                         *       EventReceive(token);
                         *   }
                         *   e.SetBuffer(token.ReceiveBuffer, 0, token.ReceiveBuffer.Length);
                         * }*/

                        Socket s = token.socket;//Available的用法不太明确,但是这里有大概率是!=0的
                        //if (s.Available != 0)
                        //{
                        //    DxDebug.LogWarning("SocketListener.OnCompletedProcessReceive():s.Available != 0");
                        //}
                        e.SetBuffer(token.ReceiveBuffer, 0, token.ReceiveBuffer.Length);
                        if (EventReceive != null)//产生接收事件,通知线程进行解包
                        {
                            EventReceive(token);
                        }
                        PrepareReceive(s, e); //开始下一个接收
                    }
                    else
                    {
                        this.ProcessError(e);
                    }
                }
                else
                {
                    DxDebug.LogWarning("SocketListener.OnCompletedProcessReceive():BytesTransferred函数返回了零,说明远程已经关闭了连接,关闭这个用户。");
                    Token token = e.UserToken as Token;
                    TokenManager.GetInstance().DeleteToken(token.ID, TokenErrorType.BytesTransferredZero);//关闭Token
                    // token.Close();
                }
            }
            catch (Exception ex)
            {
                DxDebug.LogWarning("SocketListener.OnCompletedProcessReceive():异常:" + ex.Message);
            }
        }