/// <summary> /// 处理发送完成 /// </summary> /// <param name="ioEventArgs"></param> private void ProcessSend(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (ioEventArgs.SocketError == SocketError.Success) { dataToken.dataBytesDone += ioEventArgs.BytesTransferred; if (dataToken.dataBytesDone < dataToken.data.Length) { //数据很大,没有一次发送完成 PostSend(ioEventArgs); } else { //当前队列已经发送完成,发送队列中下一个数据 DequeueAndPostSend(dataToken.Socket, ioEventArgs); } } else { //发送出错,关闭socket dataToken.Socket.ResetSendFlag(); Closing(ioEventArgs); } }
/// <summary> /// IO完成 /// </summary> /// <param name="sender"></param> /// <param name="ioEventArgs"></param> private void IO_Completed(object sender, SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; try { switch (ioEventArgs.LastOperation) { case SocketAsyncOperation.Receive: ProcessReceive(ioEventArgs); break; case SocketAsyncOperation.Send: ProcessSend(ioEventArgs); break; default: throw new ArgumentException("The last operation completed on the socket was not a receive or send"); } } catch (ObjectDisposedException) { ReleaseIOEventArgs(ioEventArgs); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
/// <summary> /// 初始化 /// </summary> private void Init() { //初始化Buffer(申请Buffer内存) bufferManager.InitBuffer(); //填充Accept池 for (int i = 0; i < socketSettings.MaxAcceptOps; i++) { acceptEventArgsPool.Push(CreateAcceptEventArgs()); } //填充IO池 SocketAsyncEventArgs ioEventArgs; for (int i = 0; i < socketSettings.NumOfRecSend; i++) { ioEventArgs = new SocketAsyncEventArgs(); bufferManager.SetBuffer(ioEventArgs); //设置IO缓冲区 ioEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); DataToken dataToken = new DataToken(); dataToken.bufferOffset = ioEventArgs.Offset; ioEventArgs.UserToken = dataToken; ioEventArgsPool.Push(ioEventArgs); } }
/// <summary> /// 尝试发送数据 /// </summary> /// <param name="socket"></param> /// <param name="ioEventArgs"></param> private void DequeueAndPostSend(GSSocket socket, SocketAsyncEventArgs ioEventArgs) { try { byte[] data; if (socket.Dequeue(out data)) //获取发送队列中的数据 { if (ioEventArgs == null) { ioEventArgs = ioEventArgsPool.Pop(); ioEventArgs.AcceptSocket = socket.WorkSocket; } DataToken dataToken = (DataToken)ioEventArgs.UserToken; dataToken.Socket = socket; dataToken.data = data; dataToken.dataBytesDone = 0; //投递发送 PostSend(ioEventArgs); } else { //发送结束 ReleaseIOEventArgs(ioEventArgs); socket.ResetSendFlag(); } } catch (Exception ex) { socket.ResetSendFlag(); Console.WriteLine(ex.ToString()); } }
/// <summary> /// 处理接收 /// </summary> /// <param name="ioEventArgs"></param> private void ProcessReceive(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (ioEventArgs.BytesTransferred == 0) { //客户端主动关闭连接 Closing(ioEventArgs); return; } if (ioEventArgs.SocketError != SocketError.Success) { //Socket错误 Closing(ioEventArgs); return; } GSSocket gsSocket = dataToken == null ? null : dataToken.Socket; byte[] buffer = new byte[ioEventArgs.BytesTransferred]; Buffer.BlockCopy(ioEventArgs.Buffer, dataToken.bufferOffset, buffer, 0, buffer.Length); PostReceive(ioEventArgs); }
/// <summary> /// 处理Accept /// </summary> /// <param name="acceptEventArgs"></param> private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs) { try { maxConnectionsEnforcer.WaitOne(); if (acceptEventArgs.SocketError != SocketError.Success) { HandleBadAccept(acceptEventArgs); } else { //投递接收事件 SocketAsyncEventArgs ioEventArgs = ioEventArgsPool.Pop(); ioEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket; DataToken dataToken = (DataToken)ioEventArgs.UserToken; ioEventArgs.SetBuffer(dataToken.bufferOffset, socketSettings.BufferSize); GSSocket gsSocket = new GSSocket(ioEventArgs.AcceptSocket); dataToken.Socket = gsSocket; acceptEventArgs.AcceptSocket = null; PostReceive(ioEventArgs); //释放acceptArgs ReleaseAccept(acceptEventArgs, false); } } finally { //投递下一个Accept事件 PostAccept(); } }
/// <summary> /// 释放IOEventArgs /// </summary> /// <param name="ioEventArgs"></param> private void ReleaseIOEventArgs(SocketAsyncEventArgs ioEventArgs) { if (ioEventArgs == null) { return; } DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (dataToken != null) { dataToken.Socket = null; } ioEventArgs.AcceptSocket = null; ioEventArgsPool.Push(ioEventArgs); }
/// <summary> /// 投递发送 /// </summary> /// <param name="ioEventArgs"></param> private void PostSend(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (dataToken.data.Length - dataToken.dataBytesDone <= socketSettings.BufferSize) { ioEventArgs.SetBuffer(dataToken.bufferOffset, dataToken.data.Length - dataToken.dataBytesDone); Buffer.BlockCopy(dataToken.data, dataToken.dataBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, dataToken.data.Length - dataToken.dataBytesDone); } else { ioEventArgs.SetBuffer(dataToken.bufferOffset, socketSettings.BufferSize); Buffer.BlockCopy(dataToken.data, dataToken.dataBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, socketSettings.BufferSize); } if (!ioEventArgs.AcceptSocket.SendAsync(ioEventArgs)) { ProcessSend(ioEventArgs); } }
/// <summary> /// 关闭 /// </summary> /// <param name="ioEventArgs"></param> private void Closing(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; try { if (ioEventArgs.AcceptSocket != null) { ioEventArgs.AcceptSocket.Shutdown(SocketShutdown.Both); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { CloseSocket(ioEventArgs); ReleaseIOEventArgs(ioEventArgs); maxConnectionsEnforcer.Release(); } }
/// <summary> /// 初始化 /// </summary> private void Init() { //初始化Buffer(申请Buffer内存) bufferManager.InitBuffer(); //填充Accept池 for (int i = 0; i < socketSettings.MaxAcceptOps; i++) { acceptEventArgsPool.Push(CreateAcceptEventArgs()); } //填充IO池 SocketAsyncEventArgs ioEventArgs; for (int i = 0; i < socketSettings.NumOfRecSend; i++) { ioEventArgs = new SocketAsyncEventArgs(); bufferManager.SetBuffer(ioEventArgs); //设置IO缓冲区 ioEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); DataToken dataToken = new DataToken(); dataToken.bufferOffset = ioEventArgs.Offset; ioEventArgs.UserToken = dataToken; ioEventArgsPool.Push(ioEventArgs); } }