private void TryDequeueAndPostSend() { byte[] data; if (sendQueue.TryDequeue(out data)) { AsyncUserToken dataToken = sendDataToken; dataToken.messageBytes = data; dataToken.messageLength = data.Length; SendBuffer(); } else { ResetSendFlag(); } }
private void PostSend(SocketAsyncEventArgs ioEventArgs) { AsyncUserToken dataToken = (AsyncUserToken)ioEventArgs.UserToken; if (dataToken.messageLength - dataToken.messageBytesDone <= this.socketSettings.BufferSize) { ioEventArgs.SetBuffer(dataToken.bufferOffset, dataToken.messageLength - dataToken.messageBytesDone); Buffer.BlockCopy(dataToken.messageBytes, dataToken.messageBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, dataToken.messageLength - dataToken.messageBytesDone); } else { ioEventArgs.SetBuffer(dataToken.bufferOffset, this.socketSettings.BufferSize); Buffer.BlockCopy(dataToken.messageBytes, dataToken.messageBytesDone, ioEventArgs.Buffer, dataToken.bufferOffset, this.socketSettings.BufferSize); } var willRaiseEvent = ioEventArgs.AcceptSocket.SendAsync(ioEventArgs); if (!willRaiseEvent) { ProcessSend(ioEventArgs); } }
/// <summary> /// Posts the send. /// </summary> public void PostSend(TcpConnect tcpConn, byte[] data, int offset, int count) { int P = NetPacketParser.PREFIX_SIZE; byte[] buffer = new byte[count + P]; Buffer.BlockCopy(BitConverter.GetBytes((UInt16)count), 0, buffer, 0, P); Buffer.BlockCopy(data, offset, buffer, P, count); tcpConn.Enqueue(buffer); if (tcpConn.TrySetSendFlag()) { try { AsyncUserToken dataToken = (AsyncUserToken)tcpConn.SendEventArgs.UserToken; dataToken.Reset(true); TryDequeueAndPostSend(tcpConn); } catch { tcpConn.ResetSendFlag(); throw; } } }
private void ProcessSend(SocketAsyncEventArgs ioEventArgs) { AsyncUserToken dataToken = (AsyncUserToken)ioEventArgs.UserToken; if (dataToken == null) { Log.Log.Net.Info("ProcessSend dataToken==null"); return; } else { if (dataToken.tcpConn == null) { Log.Log.Net.Info("ProcessSend dataToken.tcpConn==null"); return; } else { if (dataToken.tcpConn.SendEventArgs != ioEventArgs) { Log.Log.Net.Info("ProcessSend dataToken.tcpConn.SendEventArgs != ioEventArgs"); return; } } } if (ioEventArgs.SocketError == SocketError.Success) { dataToken.messageBytesDone += ioEventArgs.BytesTransferred; if (dataToken.messageBytesDone != dataToken.messageLength) { PostSend(ioEventArgs); } else { if (TestLag) { var nt = System.DateTime.Now.Ticks; //IDllImportAPI.HighPrecision_GetTickCount(); if ((nt - dataToken.SendTime) > 5000) { Log.Log.Net.Info("Send waste {0}", nt - dataToken.SendTime); } } dataToken.Reset(true); try { TryDequeueAndPostSend(dataToken.tcpConn); } catch { dataToken.tcpConn.ResetSendFlag(); throw; } } } else { //Log.FileLog.WriteLine("ProcessSend ioEventArgs.SocketError"); dataToken.tcpConn.ResetSendFlag(); HandleCloseSocket(ioEventArgs); } }
/// <summary> /// 处理数据接收回调 /// </summary> private void ProcessReceive(SocketAsyncEventArgs ioEventArgs) { AsyncUserToken dataToken = (AsyncUserToken)ioEventArgs.UserToken; if (ioEventArgs.SocketError != SocketError.Success) { //Socket错误 //Trace.TraceError("ProcessReceive:{0}", ioEventArgs.SocketError); HandleCloseSocket(ioEventArgs); return; } if (ioEventArgs.BytesTransferred == 0) { HandleCloseSocket(ioEventArgs); return; } var tcpConn = dataToken.tcpConn; #region 消息包解析 int remainingBytesToProcess = ioEventArgs.BytesTransferred; //bool needPostAnother = true; do { if (dataToken.prefixBytesDone < NetPacketParser.PREFIX_SIZE) { remainingBytesToProcess = NetPacketParser.HandlePrefix(ioEventArgs, dataToken, remainingBytesToProcess); if (dataToken.IsPrefixReady && (dataToken.messageLength > 65535 || dataToken.messageLength <= 0)) { //消息头已接收完毕,并且接收到的消息长度已经超长,socket传输的数据已紊乱,关闭掉 Log.FileLog.WriteLine("{0} Receive Ip {2} message length error:{1}", DateTime.Now.ToString("HH:mm:ss"), dataToken.messageLength, ioEventArgs.RemoteEndPoint); //needPostAnother = false; HandleCloseSocket(ioEventArgs); return; } if (remainingBytesToProcess == 0) { break; } } remainingBytesToProcess = NetPacketParser.HandleMessage(ioEventArgs, dataToken, remainingBytesToProcess); if (dataToken.IsMessageReady) { RecvEventArg evtArg = new RecvEventArg(dataToken.tcpConn, dataToken.messageBytes); if (TestLag) { evtArg.ReceiveTime = System.DateTime.Now.Ticks; //IDllImportAPI.HighPrecision_GetTickCount(); } recvQueue.Enqueue(evtArg); if (remainingBytesToProcess != 0) { 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.IsPrefixReady && dataToken.IsMessageReady) { dataToken.Reset(true); } dataToken.bufferSkip = 0; PostReceive(ioEventArgs); } }