// Add a SocketAsyncEventArg instance to the pool // //The "item" parameter is the AsyncUserToken instance // to add to the pool public void Push(AsyncUserToken item) { if (item == null) { throw new ArgumentNullException("Items added to a SocketAsyncEventArgsPool cannot be null"); } lock (m_pool) { m_pool.Push(item); } lock (h_pool) { h_pool.Remove(item); } }
/// <summary> /// 初始化函数 /// </summary> public void Init() { AsyncUserToken userToken; for (int i = 0; i < _maxClient; i++) { userToken = new AsyncUserToken(BufferSize); _userTokenPool.Push(userToken); } //心跳检测 Thread tCheckClientHeartbeat = new Thread(CheckClientHeartbeat); tCheckClientHeartbeat.IsBackground = true; tCheckClientHeartbeat.Start(); }
/// <summary> /// 监听Socket接受处理 /// </summary> /// <param name="e">SocketAsyncEventArg associated with the completed accept operation.</param> private void ProcessAccept(SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { Socket sock = e.AcceptSocket;//和客户端关联的socket if (sock.Connected) { AsyncUserToken userToken = null; try { //确保和_clientCount逻辑一致 _maxAcceptedClients.WaitOne(); Interlocked.Increment(ref _clientCount);//原子操作加1 userToken = _userTokenPool.Pop(); if (userToken != null) { userToken.ConnectSocket = sock; _logger.Debug("Client {0} connected, Totoal {1} Connections", sock.RemoteEndPoint.ToString(), _clientCount); if (!sock.ReceiveAsync(userToken.ReceiveEventArgs))//投递接收请求 { ProcessReceive(userToken.ReceiveEventArgs); } } } catch (Exception ex) { _logger.Error(ex, "IOCP ProcessAccept {0} Data Error.", sock.RemoteEndPoint); if (userToken != null) { CloseClientSocket(userToken); } else { sock.Shutdown(SocketShutdown.Both); } } } } //投递下一个接受请求 StartAccept(e); }
public AsyncUserToken GetTokenByMemberID(string memberID) { lock (h_pool) { AsyncUserToken userToken = null; for (int i = 0; i < h_pool.Count; i++) { if (h_pool[i].userInfo.Register == null) { continue; } if (h_pool[i].userInfo.Register.userID == memberID) { userToken = h_pool[i]; break; } } return(userToken); } }
/// <summary> ///接收完成时处理函数 /// </summary> /// <param name="e">与接收完成操作相关联的SocketAsyncEventArg对象</param> private void ProcessReceive(SocketAsyncEventArgs e) { AsyncUserToken userToken = null; try { userToken = e.UserToken as AsyncUserToken; if (userToken.ReceiveEventArgs.BytesTransferred > 0 && userToken.ReceiveEventArgs.SocketError == SocketError.Success) { Socket sock = userToken.ConnectSocket; //判断所有需接收的数据是否已经完成 if (sock != null && sock.Available == 0) { //把收到的数据写入到缓存区里面 userToken.ReceiveBuffer.WriteBuffer(e.Buffer, e.Offset, e.BytesTransferred); //TODO 处理数据 //string info = Encoding.Default.GetString(e.Buffer, e.Offset, e.BytesTransferred); //Log4Debug(String.Format("收到 {0} 数据为 {1}", sock.RemoteEndPoint.ToString(), info)); Send(userToken.SendEventArgs, e.Buffer); } if (sock != null && !sock.ReceiveAsync(userToken.ReceiveEventArgs))//为接收下一段数据,投递接收请求,这个函数有可能同步完成,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件 { //同步接收时处理接收完成事件 ProcessReceive(userToken.ReceiveEventArgs); } } else { CloseClientSocket(userToken); } } catch (Exception ex) { CloseClientSocket(userToken); _logger.Error(ex, "IOPC ProcessReceive Error"); } }
/// <summary> /// 异步的发送数据 /// </summary> /// <param name="e"></param> /// <param name="data"></param> public void Send(SocketAsyncEventArgs e, byte[] data) { AsyncUserToken userToken = e.UserToken as AsyncUserToken; try { userToken.SendBuffer.WriteBuffer(data, 0, data.Length);//写入要发送的数据 if (userToken.SendEventArgs.SocketError == SocketError.Success) { if (userToken.ConnectSocket.Connected) { //设置发送数据 //Array.Copy(data, 0, e.Buffer, 0, data.Length); Buffer.BlockCopy(data, 0, e.Buffer, 0, data.Length); if (!userToken.ConnectSocket.SendAsync(userToken.SendEventArgs))//投递发送请求,这个函数有可能同步发送出去,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件 { // 同步发送时处理发送完成事件 ProcessSend(userToken.SendEventArgs); } userToken.SendBuffer.Clear(); } else { CloseClientSocket(userToken); } } else { CloseClientSocket(userToken); } } catch (Exception ex) { CloseClientSocket(userToken); _logger.Error(ex, "IOPC Send Error"); } }
/// <summary> /// 当Socket上的发送或接收请求被完成时,调用此函数 /// </summary> /// <param name="sender">激发事件的对象</param> /// <param name="e">与发送或接收完成操作相关联的SocketAsyncEventArg对象</param> private void OnIOCompleted(object sender, SocketAsyncEventArgs e) { // Determine which type of operation just completed and call the associated handler. AsyncUserToken userToken = e.UserToken as AsyncUserToken; lock (userToken) { switch (e.LastOperation) { case SocketAsyncOperation.Accept: ProcessAccept(e); break; case SocketAsyncOperation.Receive: ProcessReceive(e); break; //case SocketAsyncOperation.Send: // ProcessSend(e); // break; } } }
/// <summary> /// 监听Socket接受处理 /// </summary> /// <param name="e">SocketAsyncEventArg associated with the completed accept operation.</param> private void ProcessAccept(SocketAsyncEventArgs e) { Socket sock = e.AcceptSocket;//和客户端关联的socket if (e.SocketError == SocketError.Success) { if (sock.Connected) { Log4Debug("连接用户的Handle:" + sock.Handle); try { Interlocked.Increment(ref _clientCount);//原子操作加1 AsyncUserToken userToken = _userTokenPool.Pop(); userToken.Init(); userToken.ConnectSocket = sock; //创建处理数据线程 //Thread handle = new Thread(new ParameterizedThreadStart(Handle)); //handle.Start(userToken); //心跳时间 userToken.userInfo = new RoomActor(DateTime.Now); Log4Debug(String.Format("客户 {0} 连入, 共有 {1} 个连接。", sock.RemoteEndPoint.ToString(), _clientCount)); ProcessReceive(userToken);//投递接收请求 } catch (SocketException ex) { Log4Debug(String.Format("接收客户 {0} 数据出错, 异常信息: {1} 。", sock.RemoteEndPoint, ex.ToString())); //TODO 异常处理 } //投递下一个接受请求 StartAccept(e); } } }
/// <summary> /// 存储要发送的消息并判断是否发送 /// </summary> /// <param name="e"></param> /// <param name="data"></param> public void SaveSendMessage(AsyncUserToken userToken, byte[] data) { //string INFO = "保存待发送:"; //for (int i = 0; i < data.Length; i++) //{ // INFO += "_" + data[i]; //} //Log4Debug(INFO); lock (userToken.SendBuffer) { //存值 for (int i = 0; i < data.Length; i++) { //将buffer保存到队列 userToken.SendBuffer.Enqueue(data[i]); } } if (!userToken.isDealSend) { userToken.isDealSend = true; Send(userToken); } }
/// <summary> /// 关闭socket连接 /// </summary> /// <param name="e">SocketAsyncEventArg associated with the completed send/receive operation.</param> private void CloseClientSocket(AsyncUserToken userToken) { if (userToken == null || userToken.ConnectSocket == null) { return; } _logger.Debug("Client {0} Disconected, Totoal :{1}", userToken.ConnectSocket.RemoteEndPoint.ToString(), _clientCount); try { userToken.ConnectSocket.Shutdown(SocketShutdown.Both); } catch (Exception ex) { // Throw if client has closed, so it is not necessary to catch. _logger.Error(ex, "Error When Close"); } _maxAcceptedClients.Release(); Interlocked.Decrement(ref _clientCount); userToken.ConnectSocket = null; //释放引用,并清理缓存,包括释放协议对象等资源 _userTokenPool.Push(userToken); }
/// <summary> /// 初始化函数 /// </summary> public void Init() { AsyncUserToken userToken; for (int i = 0; i < _maxClient; i++) { userToken = new AsyncUserToken(_bufferSize); userToken.ReceiveEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted); userToken.SendEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted); _userTokenPool.Push(userToken); } Thread prinThread = new Thread(() => { while (true) { PrintCurrentConnections(); Thread.Sleep(1000); } }); prinThread.IsBackground = true; prinThread.Start(); }
public void Handle(object obj) { //AsyncUserToken userToken = (AsyncUserToken)obj; //while (userToken.ReceiveBuffer.Count > 0) //{ // //userToken.isOnLoop = true; // byte[] buffer = new byte[] { }; // if (userToken.HalfMessage == null)//上一次循环的数据处理完毕 // { // int startLength = MessageXieYi.XieYiLength + 1; // //TODO 处理数据 // if (userToken.ReceiveBuffer.Count < startLength) // { // Log4Debug("剩余长度:" + userToken.ReceiveBuffer.Count() + "小于协议默认长度:" + startLength); // break; // } // //查找开头标识 // byte markStart = 0; // lock (userToken.ReceiveBuffer) // { // do // { // markStart = userToken.ReceiveBuffer.Dequeue(); // } // while (markStart != MessageXieYi.markStart);//此处有可能删除数据 // } // // // //至少6位数据 解析传输数据长度 // buffer = new byte[MessageXieYi.XieYiLength]; // lock (userToken.ReceiveBuffer) // { // for (int i = 0; i < buffer.Length; i++) // { // buffer[i] = userToken.ReceiveBuffer.Dequeue(); // } // } // userToken.HalfMessage = MessageXieYi.BackMessageType(buffer);// 读取协议长度的数值来判断该协议中数据长度的数值 // } // if (userToken.HalfMessage.IsLengthCanFillMessage(userToken.ReceiveBuffer))//长度是否足够填充信息(接收数据是否够完成本次) // { // lock (userToken.ReceiveBuffer) // { // userToken.HalfMessage.FillMessageContent(userToken.ReceiveBuffer); // //检查填充完成的下一位是否是结尾符 // byte end = userToken.ReceiveBuffer.Peek(); // if (end == MessageXieYi.markEnd)//一致的话清除结尾符 // { // userToken.ReceiveBuffer.Dequeue(); // } // else // { // Log4Debug("检查->处理数据结束后的markEnd不一致:" + end); // } // } // byte[] backInfo = ServerDataManager.instance.SelectMessage(userToken.HalfMessage, userToken); //判断逻辑 // userToken.HalfMessage = null; // if (backInfo != null)//用户需要服务器返回值的话 // { // //存储要发送的消息并判断是否发送 // AsyncIOCPServer.instance.SaveSendMessage(userToken, backInfo); // } // } // else // { // string info = "接收长度不够填充完整处理,保留HalfMessage。"; // Log4Debug(info); // break; // } //} //userToken.isOnLoop = false; ///////////////2 //AsyncUserToken userToken = (AsyncUserToken)obj; //while (userToken.ReceiveBuffer.Count > 0) //{ // byte[] mix = new byte[userToken.halfReceiveMessage.Length + userToken.ReceiveBuffer.Count]; // Array.Copy(userToken.halfReceiveMessage, 0, mix, 0, userToken.halfReceiveMessage.Length); // //lock (userToken.ReceiveBuffer)//锁住以后Copy并且置空 // { // Array.Copy(userToken.ReceiveBuffer.ToArray(), 0, mix, userToken.halfReceiveMessage.Length, userToken.ReceiveBuffer.Count); // userToken.ClearReceive(); // } // do // { // MessageXieYi xieyi = MessageXieYi.FromBytes(mix); // if (xieyi != null) // { // int messageLength = xieyi.MessageContentLength + MessageXieYi.XieYiLength + 1 + 1; // byte[] backInfo = ServerDataManager.instance.SelectMessage(xieyi, userToken); //判断逻辑 // if (backInfo != null)//用户需要服务器返回值的话 // { // //存储要发送的消息并判断是否发送 // AsyncIOCPServer.instance.SaveSendMessage(userToken, backInfo); // } // mix = mix.Skip(messageLength).ToArray(); // } // else // { // string info = "sy:"; // for (int i = 0; i < mix.Length; i++) // { // info += mix[i] + ","; // } // Log4Debug("剩余未处理数据长度:" + mix.Length + "/" + info); // break; // } // } while (mix.Length > 0); // userToken.halfReceiveMessage = new byte[mix.Length]; // userToken.halfReceiveMessage = mix;//保存未处理的数据长度 //} //userToken.isDealReceive = false; //////////////2 AsyncUserToken userToken = (AsyncUserToken)obj; while (userToken.outOrders.ContainsKey(userToken.receiveIndex)) { byte[] buffer = userToken.outOrders[userToken.receiveIndex]; userToken.outOrders.Remove(userToken.receiveIndex); byte[] mix = new byte[userToken.halfReceiveMessage.Length + buffer.Length]; userToken.halfReceiveMessage.CopyTo(mix, 0); Array.Copy(buffer, 0, mix, userToken.halfReceiveMessage.Length, buffer.Length); userToken.halfReceiveMessage = new byte[] { }; userToken.receiveIndex++; MessageXieYi xieyi = MessageXieYi.FromBytes(mix); if (xieyi != null) { int messageLength = xieyi.MessageContentLength + MessageXieYi.XieYiLength + 1 + 1; //Log4Debug("快速处理协议:" + (MessageConvention)xieyi.XieYiFirstFlag); DealReceive(xieyi, userToken); mix = mix.Skip(messageLength).ToArray(); //if (mix.Length > 0) //{ // byte[] intBuff = new byte[4] { mix[0], mix[1], mix[2], mix[3] }; // int index = BitConverter.ToInt32(intBuff, 0);// 从字节数组转换成 int // mix = mix.Skip(intBuff.Length).ToArray(); // userToken.outOrders.Add(index, mix); // userToken.receiveIndex = index; // continue; //} //else //{ // break; //} } else { Array.Copy(mix, 0, userToken.halfReceiveMessage, 0, mix.Length); string info = "sy:"; for (int i = 0; i < mix.Length; i++) { info += mix[i] + ","; } //Debug.LogError("剩余未处理数据长度:" + mix.Length + "当前帧:" + GameManager.instance.frameIndex + "/" + DataController.instance.MyRoomInfo.FrameIndex + info); break; } } userToken.isDealReceive = false; }
private void ReceiveCallback(IAsyncResult ar) { AsyncUserToken userToken = (AsyncUserToken)ar.AsyncState; Socket socket = userToken.ConnectSocket; try { if (socket == null || !socket.Connected) { return; } lock (userToken.ReceiveBuffer) { //从远程设备读取数据 int read = socket.EndReceive(ar); if (read > 0) { //byte[] buffer = new byte[read]; ////将getBuffer数组的前read个字节拷贝到buffer数组中 //Array.Copy(userToken.AsyncReceiveBuffer, 0, buffer, 0, read); //userToken.userInfo.heartbeatTime = DateTime.Now; ////接收数据保存以后继续接收 //ProcessReceive(userToken); //lock (userToken.ReceiveBuffer) //{ // //存值 // for (int i = 0; i < buffer.Length; i++) // { // //将buffer保存到队列 // userToken.ReceiveBuffer.Enqueue(buffer[i]); // } //} //if (!userToken.isDealReceive) //{ // userToken.isDealReceive = true; // Handle(userToken); //} byte[] buffer = new byte[read]; //将getBuffer数组的前read个字节拷贝到buffer数组中 Array.Copy(userToken.AsyncReceiveBuffer, 0, buffer, 0, read); //接收数据保存以后继续接收 ProcessReceive(userToken); string info = ""; for (int i = 0; i < buffer.Length; i++) { info += buffer[i] + ","; } //Log4Debug("接收数据:" + info); MessageOperation oper = MessageOperation.FromBytes(buffer); userToken.outOrders.Add(oper.GetId(), oper.Message); //byte[] intBuff = new byte[4] { buffer[0], buffer[1], buffer[2], buffer[3] }; //int index = BitConverter.ToInt32(intBuff, 0); // 从字节数组转换成 int //byte[] dealBuffer = new byte[buffer.Length - intBuff.Length]; //Array.Copy(buffer, intBuff.Length, dealBuffer, 0, dealBuffer.Length); //userToken.outOrders.Add(index, dealBuffer); //while (userToken.outOrders.ContainsKey(userToken.sendIndex)) //{ // //存值 // for (int i = 0; i < userToken.outOrders[userToken.sendIndex].Length; i++) // { // //将buffer保存到队列 // userToken.ReceiveBuffer.Enqueue(userToken.outOrders[userToken.sendIndex][i]); // } // userToken.sendIndex++; //} if (!userToken.isDealReceive) { userToken.isDealReceive = true; Handle(userToken); } } else//接收数据小于等于0 { CloseClientSocket(userToken); return; } } } catch (Exception error) { Log4Debug("ReceiveError:" + error.Message); CloseClientSocket(userToken); } }
///// <summary> ///// 同步发送方法 ///// </summary> ///// <param name="e"></param> ///// <param name="timeout">同步发送的延迟毫秒</param> //public void Send(AsyncUserToken e, byte[] data) //{ // AsyncUserToken userToken = e; // try // { // //if (!userToken.ConnectSocket.Connected) // //{ // // OffLineClientSocket(userToken); // //} // userToken.ConnectSocket.SendTimeout = 0; // //int startTickCount = Environment.TickCount; // try // { // userToken.ConnectSocket.Send(data, data.Length, SocketFlags.None); // } // catch (SocketException ex) // { // if ( // ex.SocketErrorCode == SocketError.WouldBlock // || ex.SocketErrorCode == SocketError.IOPending // || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable // ) // { // // socket buffer is probably full, wait and try again // Thread.Sleep(30); // // // Log4Debug("发送失败?"); // } // else // { // OffLineClientSocket(userToken); // /*throw ex;*/ // any serious error occurr // } // } // } // catch (Exception error) // { // Log4Debug("SendError:" + error.Message); // OffLineClientSocket(userToken); // } //} public void Send(AsyncUserToken userToken) { Socket socket = userToken.ConnectSocket; //判断Socket是否存在以及是否掉线 if (socket == null) { if (userToken.userInfo != null) { instance.Log4Debug("玩家掉线:" + userToken.userInfo.Register.name); userToken.userInfo.CurState = RoomActorState.Offline; } return; } else if (!socket.Connected)//发送数据时检测到Socket掉线 { return; } //开始发送 socket.SendTimeout = 10000;//设置发送后判断超时的时长 while (userToken.SendBuffer.Count > 0) { byte[] mix = new byte[userToken.SendBuffer.Count]; lock (userToken.SendBuffer) { Array.Copy(userToken.SendBuffer.ToArray(), 0, mix, 0, userToken.SendBuffer.Count); userToken.ClearSend(); } //int startTickCount = Environment.TickCount; while (mix.Length > 0) { int curIndex = userToken.sendIndex; MessageOperation oper = MessageOperation.FromBytes(curIndex, mix); byte[] buffer = null; buffer = oper.ToBytes(); userToken.sendIndex++; mix = mix.Skip(buffer.Length).ToArray(); string sendIfo = "userToken.sendIndex:" + curIndex + "----"; for (int i = 0; i < buffer.Length; i++) { sendIfo += buffer[i] + ","; } Log4Debug(sendIfo); //byte[] idBuffer = BitConverter.GetBytes(curIndex);// 将 int 转换成字节数组 //byte[] lengthBuffer = new byte[4]; //userToken.sendIndex++; //int dealLength = 0; //if (mix.Length > 1020) //{ // dealLength = 1020; //} //else //{ // dealLength = mix.Length; //} //byte[] buffer = new byte[idBuffer.Length + dealLength]; //Array.Copy(idBuffer, 0, buffer, 0, idBuffer.Length);//4 //Array.Copy(mix, 0, buffer, idBuffer.Length, dealLength);//dealLength //mix = mix.Skip(buffer.Length).ToArray(); //string sendIfo = "userToken.sendIndex:" + curIndex + "----"; //for (int i = 0; i < buffer.Length; i++) //{ // sendIfo += buffer[i] + ","; //} //Log4Debug(sendIfo); // int sent = 0; // how many bytes is already sent do { try { sent += socket.Send(buffer, sent, buffer.Length - sent, SocketFlags.None); } catch (SocketException ex) { Log4Debug("sendError:" + ex.SocketErrorCode); // if (ex.SocketErrorCode == SocketError.WouldBlock || ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) { // socket buffer is probably full, wait and try again Thread.Sleep(30); Log4Debug("睡眠30秒后继续发送。"); } else { if (ex.SocketErrorCode == SocketError.ConnectionAborted)//您的主机中的软件中止了一个已建立的连接。 { return; } //throw ex; // any serious error occurr Log4Debug("send错误:" + ex.Message); } } } while (sent < buffer.Length); //Log4Debug("发送用时毫秒:" + (Environment.TickCount - startTickCount)); } } userToken.isDealSend = false; }