private void ProcessSend(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (ioEventArgs.SocketError == SocketError.Success) { dataToken.messageBytesDone += ioEventArgs.BytesTransferred; if (dataToken.messageBytesDone != dataToken.messageLength) { PostSend(ioEventArgs); } else { dataToken.ResultCallback(ResultCode.Success); dataToken.Reset(true); try { TryDequeueAndPostSend(dataToken.Socket, ioEventArgs); } catch { dataToken.Socket.ResetSendFlag(); throw; } } } else { dataToken.ResultCallback(ResultCode.Close); dataToken.Socket.ResetSendFlag(); Closing(ioEventArgs); } }
public int HandlePrefix(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess) { if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone) { for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.DataOffset + i]; } remainingBytesToProcess = remainingBytesToProcess - 4 + dataToken.prefixBytesDone; dataToken.bufferSkip += 4 - dataToken.prefixBytesDone; dataToken.prefixBytesDone = 4; dataToken.messageLength = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0); } else { for (int i = 0; i < remainingBytesToProcess; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.DataOffset + i]; } dataToken.prefixBytesDone += remainingBytesToProcess; remainingBytesToProcess = 0; } return remainingBytesToProcess; }
public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess) { if (dataToken.messageBytesDone == 0) { dataToken.byteArrayForMessage = new byte[dataToken.messageLength]; } var nonCopiedBytes = 0; if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength) { var copyedBytes = dataToken.RemainByte; nonCopiedBytes = remainingBytesToProcess - copyedBytes; Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes); dataToken.messageBytesDone = dataToken.messageLength; dataToken.bufferSkip += copyedBytes; } else { Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess); dataToken.messageBytesDone += remainingBytesToProcess; } return(nonCopiedBytes); }
/// <summary> /// Connect this instance. /// </summary> public void Connect() { socket = new Socket(this.clientSettings.RemoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(this.clientSettings.RemoteEndPoint); connected = true; var buffer = new byte[this.clientSettings.BufferSize * 2]; this.sendEventArg = new SocketAsyncEventArgs(); this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize); this.sendDataToken = new DataToken(); this.sendDataToken.bufferOffset = this.sendEventArg.Offset; this.sendEventArg.UserToken = this.sendDataToken; this.sendEventArg.AcceptSocket = socket; this.sendEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); this.receiveEventArg = new SocketAsyncEventArgs(); this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize); this.receiveDataToken = new DataToken(); this.receiveDataToken.bufferOffset = this.receiveEventArg.Offset; this.receiveEventArg.UserToken = this.receiveDataToken; this.receiveEventArg.AcceptSocket = socket; this.receiveEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); PostReceive(); }
public int HandlePrefix(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess) { if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone) { for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.dataOffset + i]; } remainingBytesToProcess = remainingBytesToProcess - 4 + dataToken.prefixBytesDone; dataToken.bufferSkip += 4 - dataToken.prefixBytesDone; dataToken.prefixBytesDone = 4; dataToken.messageLength = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0); } else { for (int i = 0; i < remainingBytesToProcess; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = saea.Buffer[dataToken.dataOffset + i]; } dataToken.prefixBytesDone += remainingBytesToProcess; remainingBytesToProcess = 0; } return(remainingBytesToProcess); }
private bool StartProcessSend(SocketAsyncEventArgs e) { try { DataToken session = e.UserToken as DataToken; if (session.messageLength - session.messageBytesDone <= _bufferSize) { e.SetBuffer(session.bufferOffset, session.messageLength - session.messageBytesDone); Buffer.BlockCopy(session.byteArrayForMessage, session.messageBytesDone, e.Buffer, session.bufferOffset, session.messageLength - session.messageBytesDone); } else { e.SetBuffer(session.bufferOffset, _bufferSize); Buffer.BlockCopy(session.byteArrayForMessage, session.messageBytesDone, e.Buffer, session.bufferOffset, _bufferSize); } bool willRaiseEvent = true; willRaiseEvent = e.AcceptSocket.SendAsync(e); if (!willRaiseEvent) { ProcessSend(e); } return(true); } catch (Exception ex) { TraceLog.WriteError("TryProcessSend:{0}", ex); } return(false); }
private void IO_Completed(object sender, SocketAsyncEventArgs ioEventArgs) { DataToken ioDataToken = (DataToken)ioEventArgs.UserToken; try { ioDataToken.Socket.LastAccessTime = DateTime.Now; 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) { //modify disposed error ignore log //logger.Error(string.Format("IO_Completed error:{0}", error)); ReleaseIOEventArgs(ioEventArgs); } catch (Exception ex) { logger.Error(string.Format("IP {0} IO_Completed unkown error:{1}", (ioDataToken != null && ioDataToken.Socket != null ? ioDataToken.Socket.RemoteEndPoint.ToNotNullString() : ""), ex)); } }
private int HandlePrefix(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess) { if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone) { for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i]; } remainingBytesToProcess = remainingBytesToProcess - 4 + dataToken.prefixBytesDone; dataToken.bufferSkip += 4 - dataToken.prefixBytesDone; dataToken.prefixBytesDone = 4; dataToken.messageLength = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0); } else { for (int i = 0; i < remainingBytesToProcess; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i]; } dataToken.prefixBytesDone += remainingBytesToProcess; remainingBytesToProcess = 0; } return(remainingBytesToProcess); }
private void Bind(Socket acceptSocket) { var exSocket = new ExSocket(acceptSocket); exSocket.LastAccessTime = DateTime.Now; var buffer = new byte[this.clientSettings.BufferSize * 2]; this.sendEventArg = new SocketAsyncEventArgs(); this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize); var sendDataToken = new DataToken() { Socket = exSocket }; sendDataToken.bufferOffset = this.sendEventArg.Offset; this.sendEventArg.UserToken = sendDataToken; this.sendEventArg.AcceptSocket = acceptSocket; this.sendEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); this.receiveEventArg = new SocketAsyncEventArgs(); this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize); var receiveDataToken = new DataToken { Socket = exSocket, SyncSegments = new Queue <ArraySegment <byte> >() }; receiveDataToken.bufferOffset = this.receiveEventArg.Offset; this.receiveEventArg.UserToken = receiveDataToken; this.receiveEventArg.AcceptSocket = acceptSocket; this.receiveEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); DataReceived += OnReceived; requestHandler.Bind(this); }
private void IO_Completed(object sender, SocketAsyncEventArgs e) { try { DataToken ioDataToken = (DataToken)e.UserToken; ioDataToken.Socket.LastAccessTime = DateTime.Now; switch (e.LastOperation) { case SocketAsyncOperation.Receive: ProcessReceive(e); break; case SocketAsyncOperation.Send: ProcessSend(e); break; default: throw new ArgumentException("The last operation completed on the socket was not a receive or send"); } } catch (Exception ex) { TraceLog.WriteError("Socket Io error:{0}", ex); } }
private void IO_Completed(object sender, SocketAsyncEventArgs ioEventArgs) { try { DataToken ioDataToken = (DataToken)ioEventArgs.UserToken; 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) { logger.Error("IO_Completed", ex); } }
public override bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List <DataMeaage> messageList) { messageList = new List <DataMeaage>(); int remainingBytesToProcess = buffer.Length; bool needPostAnother = true; do { if (dataToken.prefixBytesDone < 4) { remainingBytesToProcess = HandlePrefix(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess); if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0)) { byte[] bufferBytes = BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, dataToken.byteArrayForMessage); string data = Encoding.UTF8.GetString(bufferBytes); //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉 TraceLog.WriteWarn("Receive Ip {1} message length error:{0}\r\nData:{2}", dataToken.messageLength, (dataToken != null ? dataToken.Socket.RemoteEndPoint.ToString() : ""), data); needPostAnother = false; break; } //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess); if (remainingBytesToProcess == 0) { break; } } remainingBytesToProcess = HandleMessage(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess); if (dataToken.IsMessageReady) { //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess); messageList.Add(new DataMeaage() { Data = dataToken.byteArrayForMessage, OpCode = OpCode.Binary }); if (remainingBytesToProcess != 0) { //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip); dataToken.Reset(false); } } else { //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone); } } while (remainingBytesToProcess != 0); if (needPostAnother) { //继续处理下个请求包 if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady) { dataToken.Reset(true); } dataToken.bufferSkip = 0; } return(needPostAnother); }
private void ProcessSend(SocketAsyncEventArgs e) { DataToken session = (DataToken)e.UserToken; if (e.SocketError == SocketError.Success) { session.messageBytesDone += e.BytesTransferred; if (session.messageBytesDone != session.messageLength) { DoInternalSend(e); } else { session.Reset(true); // 触发数据发送成功事件 if (SendCompleted != null) { SendCompleted.BeginInvoke(e, null, null); } } } else { session.Reset(true); ProcessSocketError(e); } }
private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs) { SocketAsyncResult result; if (socket.TryDequeue(out result)) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; dataToken.Socket = socket; dataToken.AsyncResult = result; dataToken.byteArrayForMessage = result.Data; dataToken.messageLength = result.Data.Length; try { PostSend(ioEventArgs); } catch (Exception ex) { dataToken.ResultCallback(ResultCode.Error, ex); ResetSendFlag(); } } else { ResetSendFlag(); } }
private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs) { bool isOwner = ioEventArgs == null; byte[] data; if (socket.TryDequeue(out data)) { if (ioEventArgs == null) { ioEventArgs = ioEventArgsPool.Pop(); ioEventArgs.AcceptSocket = socket.WorkSocket; } DataToken dataToken = (DataToken)ioEventArgs.UserToken; dataToken.Socket = socket; dataToken.byteArrayForMessage = data; dataToken.messageLength = data.Length; try { PostSend(ioEventArgs); } catch { if (isOwner) { ReleaseIOEventArgs(ioEventArgs); } throw; } } else { ReleaseIOEventArgs(ioEventArgs); socket.ResetSendFlag(); } }
/// <summary> /// /// </summary> /// <param name="e"></param> /// <param name="data"></param> public void Send(SocketAsyncEventArgs e, byte[] data) { DataToken session = e.UserToken as DataToken; session.byteArrayForMessage = data; session.messageLength = data.Length; DoInternalSend(e); }
/// <summary> /// /// </summary> /// <param name="dataToken"></param> /// <param name="buffer"></param> /// <param name="messageList"></param> /// <returns></returns> public override bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List<DataMeaage> messageList) { messageList = new List<DataMeaage>(); int remainingBytesToProcess = buffer.Length; bool needPostAnother = true; do { if (dataToken.prefixBytesDone < 4) { remainingBytesToProcess = HandlePrefix(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess); if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0)) { byte[] bufferBytes = dataToken.byteArrayForMessage == null ? BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, BufferUtils.GetBytes(buffer, dataToken.bufferSkip, buffer.Length - dataToken.bufferSkip)) : BufferUtils.MergeBytes(dataToken.byteArrayForPrefix, dataToken.byteArrayForMessage, buffer); string data = Encoding.UTF8.GetString(bufferBytes); //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉 TraceLog.Write("The host[{0}] request parser head byte error, byte len={1}\r\ndata:{2}", dataToken.Socket.RemoteEndPoint.ToNotNullString(), dataToken.messageLength, data); needPostAnother = false; break; } //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess); if (remainingBytesToProcess == 0) break; } remainingBytesToProcess = HandleMessage(buffer, dataToken.bufferSkip, dataToken, remainingBytesToProcess); if (dataToken.IsMessageReady) { //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess); messageList.Add(new DataMeaage() { Data = dataToken.byteArrayForMessage, OpCode = OpCode.Binary }); if (remainingBytesToProcess != 0) { //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip); dataToken.Reset(false); } } else { //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone); } } while (remainingBytesToProcess != 0); if (needPostAnother) { //继续处理下个请求包 if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady) { dataToken.Reset(true); } dataToken.bufferSkip = 0; } return needPostAnother; }
/// <summary> /// /// </summary> /// <param name="socketObject"></param> /// <param name="data"></param> public void PushSend(SocketObject socketObject, byte[] data) { var e = _readWritePool.Pop(); e.AcceptSocket = socketObject.Connection; DataToken token = (DataToken)e.UserToken; token.Socket = socketObject; _saeaProxy.Send(e, data); }
internal void StartReceive(SocketAsyncEventArgs receiveArgs) { DataToken session = receiveArgs.UserToken as DataToken; receiveArgs.SetBuffer(session.bufferOffset, BufferSize); if (!receiveArgs.AcceptSocket.ReceiveAsync(receiveArgs)) { ProcessReceive(receiveArgs); } }
private void ProcessAccept(SocketAsyncEventArgs acceptEventArg) { try { WaitHandle.WaitAll(_resetEvent); _resetEvent[0].Set(); Socket clientSocket = acceptEventArg.AcceptSocket; if (clientSocket == null) { acceptEventArg.AcceptSocket = null; StartAccept(acceptEventArg); return; } SocketAsyncEventArgs receiveEventArgs = _readWritePool.Pop(); receiveEventArgs.AcceptSocket = acceptEventArg.AcceptSocket; DataToken token = (DataToken)receiveEventArgs.UserToken; SocketObject socketObject = new SocketObject(Guid.NewGuid(), acceptEventArg.AcceptSocket); socketObject.Init(); socketObject.sessionPool = _sessionPool; socketObject.LastAccessTime = DateTime.Now; token.Socket = socketObject; #if DEBUG Console.WriteLine("{0}>>{1} connect success", DateTime.Now.ToLongTimeString(), token.RemoteAddress); #endif _sessionPool.Put(socketObject); _saeaProxy.StartReceive(receiveEventArgs); _acceptPool.Push(acceptEventArg); if (ConnectCompleted != null) { ConnectCompleted.BeginInvoke(new SocketProcessEventArgs() { Socket = socketObject }, null, null); } } catch (SocketException ex) { DataToken token = acceptEventArg.UserToken as DataToken; TraceLog.WriteError("Listener Error when processing data received from {0}:\r\n{1}", acceptEventArg.RemoteEndPoint, ex); } catch (Exception ex) { TraceLog.WriteError("Listener error:{0}", ex.ToString()); } // Accept the next connection request. acceptEventArg.AcceptSocket = null; StartAccept(acceptEventArg); }
private void TryDequeueAndPostSend() { byte[] data; if (sendQueue.TryDequeue(out data)) { DataToken dataToken = sendDataToken; dataToken.byteArrayForMessage = data; dataToken.messageLength = data.Length; PostSend(); } else { ResetSendFlag(); } }
private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs) { byte[] data; if (socket.TryDequeue(out data)) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; dataToken.Socket = socket; dataToken.byteArrayForMessage = data; dataToken.messageLength = data.Length; PostSend(ioEventArgs); } else { ResetSendFlag(); } }
private void PostSend(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (dataToken.messageLength - dataToken.messageBytesDone <= this.socketSettings.BufferSize) { ioEventArgs.SetBuffer(dataToken.bufferOffset, dataToken.messageLength - dataToken.messageBytesDone); Buffer.BlockCopy(dataToken.byteArrayForMessage, dataToken.messageBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, dataToken.messageLength - dataToken.messageBytesDone); } else { ioEventArgs.SetBuffer(dataToken.bufferOffset, this.socketSettings.BufferSize); Buffer.BlockCopy(dataToken.byteArrayForMessage, dataToken.messageBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, this.socketSettings.BufferSize); } var willRaiseEvent = ioEventArgs.AcceptSocket.SendAsync(ioEventArgs); if (!willRaiseEvent) { ProcessSend(ioEventArgs); } }
private void Init() { this.bufferManager.InitBuffer(); for (int i = 0; i < this.socketSettings.MaxAcceptOps; i++) { this.acceptEventArgsPool.Push(CreateAcceptEventArgs()); } SocketAsyncEventArgs ioEventArgs; for (int i = 0; i < this.socketSettings.NumOfSaeaForRecSend; i++) { ioEventArgs = new SocketAsyncEventArgs(); this.bufferManager.SetBuffer(ioEventArgs); ioEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); DataToken dataToken = new DataToken(); dataToken.bufferOffset = ioEventArgs.Offset; ioEventArgs.UserToken = dataToken; this.ioEventArgsPool.Push(ioEventArgs); } }
private void TryDequeueAndPostSend(ExSocket socket, SocketAsyncEventArgs ioEventArgs) { bool isOwner = ioEventArgs == null; SocketAsyncResult result; if (socket.TryDequeue(out result)) { if (ioEventArgs == null) { ioEventArgs = ioEventArgsPool.Pop(); ioEventArgs.AcceptSocket = socket.WorkSocket; } DataToken dataToken = (DataToken)ioEventArgs.UserToken; dataToken.Socket = socket; dataToken.AsyncResult = result; dataToken.byteArrayForMessage = result.Data; dataToken.messageLength = result.Data.Length; try { PostSend(ioEventArgs); } catch (Exception ex) { dataToken.ResultCallback(ResultCode.Error, ex); if (isOwner) { ReleaseIOEventArgs(ioEventArgs); } socket.ResetSendFlag(); } } else { ReleaseIOEventArgs(ioEventArgs); socket.ResetSendFlag(); } }
private int HandleMessage(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess) { if (dataToken.messageBytesDone == 0) { dataToken.byteArrayForMessage = new byte[dataToken.messageLength]; } var nonCopiedBytes = 0; if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength) { var copyedBytes = dataToken.RemainByte; nonCopiedBytes = remainingBytesToProcess - copyedBytes; Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes); dataToken.messageBytesDone = dataToken.messageLength; dataToken.bufferSkip += copyedBytes; } else { Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess); dataToken.messageBytesDone += remainingBytesToProcess; } return(nonCopiedBytes); }
public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess) { if (dataToken.messageBytesDone == 0) { dataToken.byteArrayForMessage = new byte[dataToken.messageLength]; } var nonCopiedBytes = 0; if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength) { var copyedBytes = dataToken.RemainByte; nonCopiedBytes = remainingBytesToProcess - copyedBytes; Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes); dataToken.messageBytesDone = dataToken.messageLength; dataToken.bufferSkip += copyedBytes; } else { Buffer.BlockCopy(saea.Buffer, dataToken.DataOffset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess); dataToken.messageBytesDone += remainingBytesToProcess; } return nonCopiedBytes; }
/// <summary> /// /// </summary> /// <param name="dataToken"></param> /// <param name="buffer"></param> /// <param name="messageList"></param> /// <returns></returns> public abstract bool TryReadMeaage(DataToken dataToken, byte[] buffer, out List<DataMeaage> messageList);
/// <summary> /// 处理数据接收回调 /// </summary> /// <param name="ioEventArgs"></param> private void ProcessReceive(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (ioEventArgs.SocketError != SocketError.Success) { //Socket错误 //if (logger.IsDebugEnabled) logger.Debug("ProcessReceive:{0}", ioEventArgs.SocketError); HandleCloseSocket(ioEventArgs); return; } if (ioEventArgs.BytesTransferred == 0) { //对方主动关闭socket //if (logger.IsDebugEnabled) logger.Debug("对方关闭Socket"); HandleCloseSocket(ioEventArgs); return; } var exSocket = dataToken.Socket; #region 数据解析 List <byte[]> msgs = new List <byte[]>(); int remainingBytesToProcess = ioEventArgs.BytesTransferred; bool needPostAnother = true; do { if (dataToken.prefixBytesDone < 4) { remainingBytesToProcess = prefixHandler.HandlePrefix(ioEventArgs, dataToken, remainingBytesToProcess); if (dataToken.prefixBytesDone == 4 && (dataToken.messageLength > 10 * 1024 * 1024 || dataToken.messageLength <= 0)) { //消息头已接收完毕,并且接收到的消息长度大于10M,socket传输的数据已紊乱,关闭掉 logger.Warn("接收到的消息长度错误:{0}", dataToken.messageLength); needPostAnother = false; HandleCloseSocket(ioEventArgs); break; } //if (logger.IsDebugEnabled) logger.Debug("处理消息头,消息长度[{0}],剩余字节[{1}]", dataToken.messageLength, remainingBytesToProcess); if (remainingBytesToProcess == 0) { break; } } remainingBytesToProcess = messageHandler.HandleMessage(ioEventArgs, dataToken, remainingBytesToProcess); if (dataToken.IsMessageReady) { //if (logger.IsDebugEnabled) logger.Debug("完整封包 长度[{0}],总传输[{1}],剩余[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, remainingBytesToProcess); msgs.Add(dataToken.byteArrayForMessage); if (remainingBytesToProcess != 0) { //if (logger.IsDebugEnabled) logger.Debug("重置缓冲区,buffskip指针[{0}]。", dataToken.bufferSkip); dataToken.Reset(false); } } else { //if (logger.IsDebugEnabled) logger.Debug("不完整封包 长度[{0}],总传输[{1}],已接收[{2}]", dataToken.messageLength, ioEventArgs.BytesTransferred, dataToken.messageBytesDone); } } while (remainingBytesToProcess != 0); #endregion if (needPostAnother) { if (dataToken.prefixBytesDone == 4 && dataToken.IsMessageReady) { dataToken.Reset(true); } dataToken.bufferSkip = 0; PostReceive(ioEventArgs); } foreach (var m in msgs) { try { OnDataReceived(new ConnectionEventArgs { Socket = exSocket, Data = m }); } catch (Exception ex) { TraceLog.WriteError("OnDataReceived error:{0}", ex); } } }
private void ProcessReceive(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (ioEventArgs.BytesTransferred == 0) { //对方主动关闭socket //if (logger.IsDebugEnabled) logger.Debug("对方关闭Socket"); Closing(ioEventArgs, OpCode.Empty); return; } if (ioEventArgs.SocketError != SocketError.Success) { //Socket错误 //if (logger.IsDebugEnabled) logger.Debug("Socket接收错误:{0}", ioEventArg.SocketError); Closing(ioEventArgs); return; } List <DataMeaage> messages; bool hasHandshaked; bool needPostAnother = requestHandler.TryReceiveMessage(ioEventArgs, out messages, out hasHandshaked); if (hasHandshaked) { DoOpened(new SocketEventArgs() { Socket = dataToken.Socket }); } // 触发收到消息事件 if (messages != null) { foreach (var message in messages) { try { if (message.OpCode == OpCode.Close) { var statusCode = requestHandler.MessageProcessor != null ? requestHandler.MessageProcessor.GetCloseStatus(message.Data) : OpCode.Empty; if (statusCode != OpCode.Empty) { OnClosedStatus(statusCode); } Closing(ioEventArgs, OpCode.Empty); needPostAnother = false; break; } OnDataReceived(new SocketEventArgs { Source = message, Socket = dataToken.Socket }); } catch (Exception ex) { logger.Error("OnDataReceived", ex); } } } if (needPostAnother) { PostReceive(ioEventArgs); } }
/// <summary> /// Connect this instance. /// </summary> public void Connect() { socket = new Socket(this.clientSettings.RemoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.Connect(this.clientSettings.RemoteEndPoint); connected = true; var buffer = new byte[this.clientSettings.BufferSize * 2]; this.sendEventArg = new SocketAsyncEventArgs(); this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize); this.sendDataToken = new DataToken(); this.sendDataToken.bufferOffset = this.sendEventArg.Offset; this.sendEventArg.UserToken = this.sendDataToken; this.sendEventArg.AcceptSocket = socket; this.sendEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); this.receiveEventArg = new SocketAsyncEventArgs(); this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize); this.receiveDataToken = new DataToken(); this.receiveDataToken.bufferOffset = this.receiveEventArg.Offset; this.receiveEventArg.UserToken = this.receiveDataToken; this.receiveEventArg.AcceptSocket = socket; this.receiveEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); PostReceive(); }
private void Init() { this.bufferManager.InitBuffer(); for (int i = 0; i < this.socketSettings.MaxAcceptOps; i++) { this.acceptEventArgsPool.Push(CreateAcceptEventArgs()); } SocketAsyncEventArgs ioEventArgs; for (int i = 0; i < this.socketSettings.NumOfSaeaForRecSend; i++) { ioEventArgs = new SocketAsyncEventArgs(); this.bufferManager.SetBuffer(ioEventArgs); ioEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); DataToken dataToken = new DataToken(); dataToken.bufferOffset = ioEventArgs.Offset; ioEventArgs.UserToken = dataToken; this.ioEventArgsPool.Push(ioEventArgs); } }
/// <summary> /// /// </summary> /// <param name="ioEventArgs"></param> /// <param name="opCode"></param> /// <param name="reason"></param> /// <param name="dataToken"></param> protected void Dispose(SocketAsyncEventArgs ioEventArgs, sbyte opCode, string reason, DataToken dataToken) { ReleaseIOEventArgs(ioEventArgs); Dispose(dataToken.Socket, opCode, reason); }
private int HandlePrefix(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess) { if (remainingBytesToProcess >= 4 - dataToken.prefixBytesDone) { for (int i = 0; i < 4 - dataToken.prefixBytesDone; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i]; } remainingBytesToProcess = remainingBytesToProcess - 4 + dataToken.prefixBytesDone; dataToken.bufferSkip += 4 - dataToken.prefixBytesDone; dataToken.prefixBytesDone = 4; dataToken.messageLength = BitConverter.ToInt32(dataToken.byteArrayForPrefix, 0); } else { for (int i = 0; i < remainingBytesToProcess; i++) { dataToken.byteArrayForPrefix[dataToken.prefixBytesDone + i] = buffer[offset + i]; } dataToken.prefixBytesDone += remainingBytesToProcess; remainingBytesToProcess = 0; } return remainingBytesToProcess; }
/// <summary> /// /// </summary> /// <param name="saea"></param> /// <param name="dataToken"></param> /// <param name="remainingBytesToProcess"></param> /// <returns></returns> public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess) { return(HandleMessage(saea.Buffer, dataToken.DataOffset, dataToken, remainingBytesToProcess)); }
private void Bind(Socket acceptSocket) { var exSocket = new ExSocket(acceptSocket); exSocket.LastAccessTime = DateTime.Now; var buffer = new byte[this.clientSettings.BufferSize * 2]; this.sendEventArg = new SocketAsyncEventArgs(); this.sendEventArg.SetBuffer(buffer, 0, this.clientSettings.BufferSize); var sendDataToken = new DataToken() { Socket = exSocket }; sendDataToken.bufferOffset = this.sendEventArg.Offset; this.sendEventArg.UserToken = sendDataToken; this.sendEventArg.AcceptSocket = acceptSocket; this.sendEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); this.receiveEventArg = new SocketAsyncEventArgs(); this.receiveEventArg.SetBuffer(buffer, this.clientSettings.BufferSize, this.clientSettings.BufferSize); var receiveDataToken = new DataToken { Socket = exSocket, SyncSegments = new Queue<ArraySegment<byte>>() }; receiveDataToken.bufferOffset = this.receiveEventArg.Offset; this.receiveEventArg.UserToken = receiveDataToken; this.receiveEventArg.AcceptSocket = acceptSocket; this.receiveEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); DataReceived += OnReceived; requestHandler.Bind(this); }
/// <summary> /// 接收处理 /// </summary> /// <param name="e"></param> private void ProcessReceive(SocketAsyncEventArgs e) { DataToken session = e.UserToken as DataToken; if (e.BytesTransferred > 0) { if (e.SocketError == SocketError.Success) { //是否有已接收但未处理的数据 int remainingBytesToProcess = e.BytesTransferred; do { if (session.prefixBytesDone < 4) { remainingBytesToProcess = _prefixHandler.HandlePrefix(e, session, remainingBytesToProcess); if (remainingBytesToProcess == 0) { session.bufferSkip = 0; StartReceive(e); return; } } remainingBytesToProcess = _messageHandler.HandleMessage(e, session, remainingBytesToProcess); if (session.IsMessageReady) { // 触发收到消息事件 if (ReceiveCompleted != null) { byte[] data = session.byteArrayForMessage; ReceiveCompleted.BeginInvoke(new SocketProcessEventArgs() { Socket = session.Socket, Data = data }, null, null); } if (remainingBytesToProcess != 0) { session.Reset(false); } } }while (remainingBytesToProcess != 0); if (session.prefixBytesDone == 4 && session.IsMessageReady) { session.Reset(true); } session.bufferSkip = 0; StartReceive(e); } else { session.Reset(true); ProcessSocketError(e); } } else { session.Reset(true); CloseClientSocket(e); } }
/// <summary> /// 处理数据接收回调 /// </summary> /// <param name="ioEventArgs"></param> private void ProcessReceive(SocketAsyncEventArgs ioEventArgs) { DataToken dataToken = (DataToken)ioEventArgs.UserToken; if (ioEventArgs.BytesTransferred == 0) { //对方主动关闭socket //if (logger.IsDebugEnabled) logger.Debug("对方关闭Socket"); Closing(ioEventArgs, OpCode.Empty); return; } if (ioEventArgs.SocketError != SocketError.Success) { //Socket错误 logger.Debug("IP {0} ProcessReceive:{1}", (dataToken != null ? dataToken.Socket.RemoteEndPoint.ToNotNullString() : ""), ioEventArgs.SocketError); Closing(ioEventArgs); return; } ExSocket exSocket = dataToken == null ? null : dataToken.Socket; List <DataMeaage> messages; bool hasHandshaked; bool needPostAnother = requestHandler.TryReceiveMessage(ioEventArgs, out messages, out hasHandshaked); if (hasHandshaked) { OnHandshaked(new ConnectionEventArgs { Socket = exSocket }); } //modify reason:数据包接收事件触发乱序 if (messages != null) { foreach (var message in messages) { try { switch (message.OpCode) { case OpCode.Close: var statusCode = requestHandler.MessageProcessor != null ? requestHandler.MessageProcessor.GetCloseStatus(message.Data) : OpCode.Empty; if (statusCode != OpCode.Empty) { DoClosedStatus(exSocket, statusCode); } Closing(ioEventArgs, OpCode.Empty); needPostAnother = false; break; case OpCode.Ping: DoPing(new ConnectionEventArgs { Socket = exSocket, Meaage = message }); break; case OpCode.Pong: DoPong(new ConnectionEventArgs { Socket = exSocket, Meaage = message }); break; default: OnDataReceived(new ConnectionEventArgs { Socket = exSocket, Meaage = message }); break; } } catch (Exception ex) { TraceLog.WriteError("OnDataReceived error:{0}", ex); } } } if (needPostAnother) { PostReceive(ioEventArgs); //是否需要关闭连接 if (exSocket.IsClosed) { ResetSAEAObject(ioEventArgs); } } }
/// <summary> /// /// </summary> /// <param name="saea"></param> /// <param name="dataToken"></param> /// <param name="remainingBytesToProcess"></param> /// <returns></returns> public int HandleMessage(SocketAsyncEventArgs saea, DataToken dataToken, int remainingBytesToProcess) { return HandleMessage(saea.Buffer, dataToken.DataOffset, dataToken, remainingBytesToProcess); }
private int HandleMessage(byte[] buffer, int offset, DataToken dataToken, int remainingBytesToProcess) { if (dataToken.messageBytesDone == 0) { dataToken.byteArrayForMessage = new byte[dataToken.messageLength]; } var nonCopiedBytes = 0; if (remainingBytesToProcess + dataToken.messageBytesDone >= dataToken.messageLength) { var copyedBytes = dataToken.RemainByte; nonCopiedBytes = remainingBytesToProcess - copyedBytes; Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, copyedBytes); dataToken.messageBytesDone = dataToken.messageLength; dataToken.bufferSkip += copyedBytes; } else { Buffer.BlockCopy(buffer, offset, dataToken.byteArrayForMessage, dataToken.messageBytesDone, remainingBytesToProcess); dataToken.messageBytesDone += remainingBytesToProcess; } return nonCopiedBytes; }