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); } }
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); } }
/// <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(); } }
/// <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; } //} }
/// <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); } } }
private void OnSend() { if (_isDebugLog) { DxDebug.LogConsole("-----------EventHandler.OnSend():进入OnSend回调!"); } Interlocked.Decrement(ref _snedingCount); if (_packet2.SendMsgCount > 0) //如果待发送队列里有消息,不需要再判断_snedingCount < MAX_SENDING_DATA,直接开始下一次发送 { NetWorkMsg msg = _msgPool.Dequeue(); if (msg == null) { msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Send); } else { msg.Reset(NetWorkMsg.Tpye.C_Send); } AddMessage(msg); } else { } }
/// <summary> /// 根据期望大小获得一个buffer. /// autoSetValidLength为true则默认设置validLength为期望大小,否则设置为0. /// </summary> /// <param name="size">期望大小</param> /// <param name="autoSetValidLength">是否validLength会自动标记为size</param> /// <returns></returns> public ByteBuffer GetBuffer(long size, bool autoSetValidLength = false) { ByteBuffer bbf = null; if (size > maxBlockSize) { ByteBufferPool.countNew++; DxDebug.LogConsole("ByteBufferPools.GetBuffer():申请了一块过大的内存,size=" + size); //这个内存块太了,所以就不作缓存了 bbf = new ByteBuffer(size); } else { ByteBufferPool bbPool = ChoosePool(size); bbf = bbPool.GetBuffer((int)size); } if (autoSetValidLength) { bbf.validLength = (int)size; } else { bbf.validLength = 0; } return(bbf); }
private void Dispose(bool disposing) { DxDebug.LogConsole(String.Format("TokenManager.Dispose():进入了Dispose!")); if (disposed) { return; } if (disposing) { // 清理托管资源 EventAddToken = null; EventDeleteToken = null; //断开所有 DeleteAllToken(); _dictToken.Clear(); _dictToken = null; _arrToken = null; } // 清理非托管资源 //让类型知道自己已经被释放 disposed = true; }
/// <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())); }
/// <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); }
/// <summary> /// 启动服务器,会开启工作线程然后释放一个DoStart信号量。 /// </summary> /// <param name="port">端口号</param> /// <param name="threadCount">服务器使用的处理线程数量</param> /// <param name="hostName">服务器的主机IP,一般使用Any表示所有的可能IP</param> public void Start(int port, int threadCount = 1, string hostName = "Any") { try { DxDebug.LogConsole("DNServer.Start():服务器工作线程数 " + threadCount); if (disposed) { TokenManager.GetInst().Clear(); _msgQueue = new DQueue <NetWorkMsg>(MSG_QUEUE_CAPACITY); _msgSemaphore = new Semaphore(0, MSG_QUEUE_CAPACITY); _workThread = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { _workThread[i] = new Thread(DoWork); _workThread[i].IsBackground = true; //工作线程的优先级(影响不大) _workThread[i].Priority = ThreadPriority.Highest; _workThread[i].Name = "SeverThread " + i; _workThread[i].Start(); //启动线程 } disposed = false; } _port = port; NetWorkMsg msg = new NetWorkMsg(NetWorkMsg.Tpye.S_Start, null); msg.text1 = hostName; AddMessage(msg); } catch (Exception e) { DxDebug.LogError("DNServer.Start():异常 " + e.Message); } }
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(); //时间分析计时 } } }
private void DoConnect() { try { //DxDebug.LogConsole("DNClient.DoConnect():执行Connect..."); //标记正在连接 IsConnecting = true; Interlocked.Exchange(ref _snedingCount, 0); this.Clear();//清空数据 if (_socketClient != null) { //DxDebug.LogConsole("DNClient.DoConnect():断开原先连接!"); _socketClient.Disconnect(); _socketClient.Bind(_host, _port);//绑定新ip _socketClient.Clear(); DxDebug.LogConsole("DNClient.DoConnect():-----------正在连接..."); _socketClient.Connect(); DxDebug.LogConsole("DNClient.DoConnect():-----------连接服务器成功!" + _host + ":" + _port); } else { _socketClient = new SocketClient(_host, _port, _packet2); if (_socketClient == null) { DxDebug.LogError("DNClient.DoConnect():-----------连接服务器失败!_socketClient对象未能创建成功。"); return; } _socketClient.EventReceive += OnReceive; //加入接收事件 _socketClient.EventSend += OnSend; //加入发送事件 _socketClient.EventError += OnError; //加入错误事件 DxDebug.LogConsole("DNClient.DoConnect():-----------正在连接..."); _socketClient.Connect(); DxDebug.LogConsole("DNClient.DoConnect():-----------连接服务器成功!" + _host + ":" + _port); } if (EventConnectSuccess != null) { try { EventConnectSuccess(this); }//事件类型:ConnectError catch (Exception e) { DxDebug.LogError("DNClient.DoConnect():执行EventError事件异常:" + e.Message); } } } catch (Exception e) { DxDebug.LogError("DNClient.DoConnect():-----------连接服务器失败!: " + e.Message); if (EventError != null) { try { EventError(this, EventType.ConnectError, e); }//事件类型:ConnectError catch (Exception e2) { DxDebug.LogError("DNClient.DoConnect():执行EventError事件异常:" + e2.Message); } } } //标记已经结束了连接 IsConnecting = false; }
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; }
/// <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();//释放 } }
/// <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); } } } }
/// <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); } }
/// <summary> /// 初始化并且开始,如果调用了果了Dispose,那么可以重新调用这个函数再次开始。 /// </summary> public void Start() { if (disposed == false) { Dispose(); } _timer = new Timer(new TimerCallback(OnTimerTick)); _timer.Change(250, KICK_TIME); _count3S = 0; DxDebug.LogConsole("ClientTimer.Init():ClientTimer启动!"); }
/// <summary> /// 这个对象的Close()函数会调用该函数 /// </summary> public void Dispose() { DxDebug.LogWarning("DNServer.Dispose():进入了Dispose."); if (_workThread != null) { for (int i = 0; i < _workThread.Length; i++) { DxDebug.LogConsole("DNServer.Dispose():[" + _workThread[i].Name + "].IsAlive 为:" + _workThread[i].IsAlive); } } Dispose(true); }
/// <summary> /// 工作线程启动 /// </summary> public void Start() { try { //标记线程可以运行 _isRun = true; if (_disposed) { //标记自己已经有了资源申请 _disposed = false; try { DxDebug.LogConsole("WorkThread.Start():这个类对象经被释放或刚刚构造,重新初始化"); _msgQueue = new DQueue <IWorkMsg>(MSG_QUEUE_CAPACITY, _initMsgQueueSize); _msgSemaphore = new Semaphore(0, 64);//由于AddMessage的改动,这里只需要是随便一个数既可 _isWorking = new bool[_threadCount]; _lastWorkTime = new long[_threadCount]; _workThreadID = new int[_threadCount]; _workThread = new Thread[_threadCount]; for (int i = 0; i < _threadCount; i++) { _workThread[i] = new Thread(DoWork); _workThread[i].IsBackground = true; //工作线程的优先级(影响不大) _workThread[i].Priority = ThreadPriority.Highest; _workThread[i].Name = name + i; //记录线程ID _workThreadID[i] = _workThread[i].ManagedThreadId; _workThread[i].Start(); //启动线程 } } catch (Exception e) { DxDebug.LogError("WorkThread.Start():构造失败!异常:" + e.Message); Dispose(); } } else { Dispose(); Start(); } } catch (Exception e) { DxDebug.LogError("WorkThread.Start():异常:" + e.Message); } }
private void Dispose(bool disposing) { if (_disposed) { return; } try { DxDebug.LogConsole("WorkThread.DoWork():工作线程关闭!"); _isRun = false; //最先去把线程关了 for (int i = 0; i < _threadCount; i++) { //把线程关了 if (_workThread[i] != null && _workThread[i].IsAlive) { try { _workThread[i].Abort(); } catch (Exception e) { DxDebug.LogWarning("WorkThread.Dispose():异常 _workThread[" + i + "].Abort();" + e.Message); } } } if (disposing) { // 清理托管资源 if (_msgQueue != null) { _msgQueue.Clear(); } } // 清理非托管资源 if (_msgSemaphore != null) { _msgSemaphore.Close(); } } catch (Exception e) { DxDebug.LogWarning("WorkThread.Dispose():释放异常" + e.Message); } //让类型知道自己已经被释放 _disposed = true; }
/// <summary> /// 检查用户是否其实已经离线,在OnTimerTick函数里调用 /// </summary> private void CheckOffLineAndSend() { _countHeartBeatCheckTime += KICK_TIME; if (_countHeartBeatCheckTime >= Config.HeartBeatCheckTime) //15秒*1 { Interlocked.Exchange(ref _countHeartBeatCheckTime, 0); //这里要立马置零,防止后面的代码执行的过久,再次进入kick Token[] tokens = TokenManager.GetInstance().GetAllToken(); if (tokens != null) { for (int i = 0; i < tokens.Length; i++) { Token token = tokens[i]; if (token.LastMsgReceTickTime < _checkTickTime) //如果从上次的进入这里的时间之后一直都没有收到消息 { DxDebug.LogConsole("ServerTimer.CheckOffLine():一个用户长时间没有收到心跳包,被删除!"); TokenManager.GetInstance().DeleteToken(token.ID, TokenErrorType.HeartBeatTimeout);//删除这个用户 } } } _checkTickTime = DateTime.Now.Ticks; } _countHeartBeatSendTime += KICK_TIME; if (_countHeartBeatSendTime >= Config.HeartBeatSendTime) //5秒进一次 { Interlocked.Exchange(ref _countHeartBeatSendTime, 0); //这里要立马置零,防止后面的代码执行的过久,再次进入kick long subTimeTick = DateTime.Now.Ticks - 10000 * Config.HeartBeatSendTime; //计算得到的门限时间 Token[] tokens = TokenManager.GetInstance().GetAllToken(); if (tokens != null) { for (int i = 0; i < tokens.Length; i++) { Token token = tokens[i]; if (token.disposed == false && token.LastMsgSendTickTime < subTimeTick) //如果从上次的进入这里的时间之后一直都没有发消息 { //应该发送一条心跳包 token.AddSendData(Config.HeartBeatData, 0, Config.HeartBeatData.Length); } } DNServer.GetInstance().SendAll();//整体发送 } } }
/// <summary> /// 设置工作目录路径,如果传入空则表示工作路径为当前程序运行路径.通常来说在运行之前都应该指定一个目录 /// </summary> public bool SetDirCache(string dir) { try { DxDebug.LogConsole("DNServer.SetDirCache():尝试设置工作文件夹路径 dir = " + dir); if (String.IsNullOrEmpty(dir)) { dirCache = Directory.GetCurrentDirectory(); DxDebug.LogConsole("DNServer.SetDirCache():输入路径为空,所以设置文件夹为" + dirCache); } else { dirCache = dir; //赋值 } if (!Directory.Exists(dirCache)) //如果这个目录不存在,那么就尝试创建一下这个目录 { DxDebug.LogConsole("DNServer.SetDirCache():文件夹不存在,创建文件夹..."); Directory.CreateDirectory(dirCache); } string testfile = System.IO.Path.Combine(dirCache, "dirtestFile_"); DxDebug.LogConsole("DNServer.SetDirCache():进行文件读写测试..."); FileStream fs = File.Create(testfile); //创建一下试试 fs.WriteByte(0xff); fs.Flush(); fs.Close(); fs = File.Open(testfile, FileMode.Open); if (fs.ReadByte() != 0xff) { dirCache = null; return(false); } fs.Close(); File.Delete(testfile); DxDebug.LogConsole("DNClient.SetDirCache():进行文件读写测试成功"); return(true);//如果允许到这里都没有错误,那么说明这个目录可以正常使用 } catch (Exception e) { DxDebug.LogError("DNServer.SetDirCache():设置工作文件夹失败! " + e.Message); } dirCache = null; return(false); }
/// <summary> /// 初始化并且开始,如果调用了果了Dispose,那么可以重新调用这个函数再次开始。 /// 如果已经初始化,那么不会执行。 /// </summary> public void Start() { //这里不要强制释放了 //if (disposed == false) //{ // Dispose(); //} if (disposed) { _timer = new Timer(new TimerCallback(OnTimerTick)); _timer.Change(250, KICK_TIME); _checkTickTime = DateTime.Now.Ticks; DxDebug.LogConsole("ServerTimer.Init():ServerTimer启动!"); } }
/// <summary> /// 异步的关闭socket和线程,会在消息队列中执行完这个消息之前的所有消息后,才会执行。 /// </summary> public void Close() { DxDebug.LogConsole("DNClient.Close():进入了close函数!"); NetWorkMsg msg = _msgPool.Dequeue(); if (msg == null) { msg = new NetWorkMsg(NetWorkMsg.Tpye.C_AsynClose); } else { msg.Reset(NetWorkMsg.Tpye.C_AsynClose); } AddMessage(msg); }
private void OnReceive() { if (this._isDebugLog) { DxDebug.LogConsole("-----------EventHandler:进入了OnReceive回调!"); } NetWorkMsg msg = _msgPool.Dequeue(); if (msg == null) { msg = new NetWorkMsg(NetWorkMsg.Tpye.C_Receive); } else { msg.Reset(NetWorkMsg.Tpye.C_Receive); } AddMessage(msg); }
/// <summary> /// 发生了错误,通常是断开连接了 /// </summary> /// <param name="e"></param> private void ProcessError(SocketAsyncEventArgs e) { try { Token token = e.UserToken as Token; IPEndPoint localEp = token.socket.LocalEndPoint as IPEndPoint; DxDebug.LogConsole(string.Format("SocketListener.ProcessError():SocketError:{0} IP:{1} 上次操作:{2}.", e.SocketError, localEp, e.LastOperation)); TokenManager.GetInstance().DeleteToken(token.ID, e.SocketError); // token.Close();//执行关闭 if (EventError != null)// 执行事件 { EventError(token, e.SocketError); } } catch (Exception ex) { DxDebug.LogWarning("SocketListener.ProcessError():异常:" + ex.Message); } }
/// <summary> /// 在定时器中调用的函数 /// </summary> private void OnUpdate() { int cur1sReceive = CountReceive - _lastCountReceive; int cur1sSend = CountSend - _lastCountSend; int cur1sReceiveBytes = CountReceiveBytes - _lastCountReceiveBytes; int cur1sSendBytes = CountSendBytes - _lastCountSendBytes; _lastCountReceive = CountReceive; _lastCountSend = CountSend; _lastCountReceiveBytes = CountReceiveBytes; _lastCountSendBytes = CountSendBytes; CountReceive10s.EnqueueMaxLimit(cur1sReceive); //添加这一秒的结果到末尾 CountSend10s.EnqueueMaxLimit(cur1sSend); //添加这一秒的结果到末尾 CountReceiveBytes10s.EnqueueMaxLimit(cur1sReceiveBytes); //添加这一秒的结果到末尾 CountSendBytes10s.EnqueueMaxLimit(cur1sSendBytes); //添加这一秒的结果到末尾 if (isPrintCur1s && _dnServer.IsStarted) //如果设置了打印这一秒,并且服务器在工作 { DxDebug.LogConsole(String.Format("ServerStatus.OnUpdate():一秒内接收/发送:{0}/{2}条,总{4}/{5}条,消息队列长{6} ,{1:F1}/{3:F1}kB.", cur1sReceive, cur1sReceiveBytes / 1000.0f, cur1sSend, cur1sSendBytes / 1000.0f, CountReceive, CountSend, _dnServer.msgQueueLength)); } }
/// <summary> /// 开始接受客户端的Accept,使用一组SocketAsyncEventArgs /// </summary> private void StartAccept2() { //lock (_lockAccept)//这个加锁没有解决问题 //{ try { if (_acceptEventArgs == null) { _acceptEventArgs = new SocketAsyncEventArgs[2]; for (int i = 0; i < _acceptEventArgs.Length; i++) { _acceptEventArgs[i] = new SocketAsyncEventArgs(); _acceptEventArgs[i].Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted); } } for (int i = 0; i < _acceptEventArgs.Length; i++) { _acceptEventArgs[i].AcceptSocket = null; // 必须要先清掉Socket } DxDebug.LogConsole("SocketListener.StartAccept2():服务器开始接收认证!"); for (int i = 0; i < _acceptEventArgs.Length; i++) { //开始异步接收认证 if (!_listenSocket.AcceptAsync(_acceptEventArgs[i])) { this.ProcessAccept(_acceptEventArgs[i]); } } } catch (Exception e) { DxDebug.LogWarning("SocketListener.StartAccept2():异常:" + e.Message); throw; } //} }
private void DoWork() { try { DxDebug.LogConsole("DNClient.DoWork():-----------通信线程启动!"); while (true) { Interlocked.Exchange(ref _isThreadWorking, 0);//标记当前线程已经停止工作 _msgSemaphore.WaitOne(); Interlocked.Decrement(ref _curSemCount); //递减信号量计数 Interlocked.Exchange(ref _isThreadWorking, 1); //标记当前线程已经正在执行工作 //_cpuTime.WorkStart(); //时间分析计时 while (true) { NetWorkMsg msg = _msgQueue.Dequeue(); if (msg == null) { break; } float waitTime = (DateTime.Now.Ticks - msg.timeTickCreat) / 10000;//毫秒 if (waitTime > _warringWaitTime) { _warringWaitTime += 500; DxDebug.LogWarning("DNClient.DoWork():NetWorkMsg等待处理时间过长!waitTime:" + waitTime); } else if ((_warringWaitTime - waitTime) > 500) { _warringWaitTime -= 500; } if (msg != null) { switch (msg.type) { case NetWorkMsg.Tpye.C_Connect: DoConnect(); break; case NetWorkMsg.Tpye.C_Send: DoSend(msg); break; case NetWorkMsg.Tpye.C_Receive: DoReceive(); break; case NetWorkMsg.Tpye.C_AsynClose: DoClose(); _workThread = null; //把这个成员置为空 return; //执行完就结束了整个线程函数 default: break; } //用过的消息放回池里 _msgPool.EnqueueMaxLimit(msg); } else { // _cpuTime.Calculate();//空闲的话就计算一下 } //long costTime = _cpuTime.WaitStart(); //时间分析计时 } } } catch (Exception e) { DxDebug.LogError("DNClient.DoWork():异常:通信线程执行异常! " + e.Message); } }