protected void OnRecvBytesCallback(IAsyncResult res) { try { int len = _socket.EndReceive(res); _bRecving = false; if (len <= 0) { LogManager.Debug("TcpSession::OnRecvBytesCallback => disconnected by remote"); Stop(); return; } DataBuff buff = res.AsyncState as DataBuff; if (buff == null) { LogManager.Debug("TcpSession::OnRecvBytesCallback => invalid recv buffer"); return; } buff._dataLen += (uint)len; lock (_recvLocker) { _recvBuffList.Add(buff); } RecvBytes(); } catch (SocketException e) { LogManager.Debug(string.Format("TcpSession::OnRecvBytesCallback => error [{0}] [{1}]", e.ErrorCode, e.Message)); } catch { LogManager.Debug("TcpSession::OnRecvBytesCallback => unknown error"); } }
protected void RecvBytes() { if (!IsConnected()) { LogManager.Debug("TcpSession::SendBytes => not connected"); return; } if (_bRecving) { return; } try { DataBuff buff = null; lock (_recvLocker) { if (_recvBuffList.Count > 0) { int index = _recvBuffList.Count - 1; if (_recvBuffList[index] != null && _recvBuffList[index].GetUnwriteLen() > 0) { buff = _recvBuffList[index]; _recvBuffList.RemoveAt(index); } } } if (buff == null) { buff = ObjectPool <DataBuff> .Pop(); } _socket.BeginReceive(buff._data, 0, (int)buff.GetUnwriteLen(), SocketFlags.None, OnRecvBytesCallback, buff); _bRecving = true; } catch (SocketException e) { LogManager.Debug(string.Format("TcpSession::RecvBytes => error [{0}] [{1}]", e.ErrorCode, e.Message)); } catch { LogManager.Debug("TcpSession::RecvBytes => unknown error"); } }
protected void SendBytes() { if (!IsConnected()) { LogManager.Debug("TcpSession::SendBytes => not connected"); return; } if (_bSending) { return; } DataBuff buff = null; lock (_sendLocker) { if (_sendBuffList.Count <= 0) { return; } buff = _sendBuffList[0]; _sendBuffList.RemoveAt(0); } if (buff == null) { return; } try { _socket.BeginSend(buff._data, 0, (int)buff._dataLen, SocketFlags.None, OnSendBytesCallback, buff); _bSending = true; } catch (SocketException e) { LogManager.Debug(string.Format("TcpSession::SendBytes => error [{0}] [{1}]", e.ErrorCode, e.Message)); } catch { LogManager.Debug("TcpSession::SendBytes => unknown error"); } }
protected void OnSendBytesCallback(IAsyncResult res) { try { int len = _socket.EndSend(res); _bSending = false; DataBuff buff = res.AsyncState as DataBuff; if (buff == null || len != buff._dataLen) { LogManager.Debug("TcpSession::OnSendBytesCallback => send error"); Stop(); return; } buff.Clear(); ObjectPool <DataBuff> .Push(buff); SendBytes(); } catch (SocketException e) { LogManager.Debug(string.Format("TcpSession::OnSendBytesCallback => error [{0}] [{1}]", e.ErrorCode, e.Message)); } catch { LogManager.Debug("TcpSession::OnSendBytesCallback => unknown error"); } }
public void PushSendData(ushort msgType, ISerializableObj data) { if (!IsConnected()) { return; } uint dataLen = data == null ? 0 : data.CalcDataLen(); uint needLen = dataLen + 4; uint copyLen = 0; DataBuff buff = null; List <DataBuff> sendBuffList = new List <DataBuff>(); if (needLen > FileDataBuff.MAX_FILE_SIZE) { return; } if (needLen > DataBuff.MAX_BUFF_LEN) { buff = ObjectPool <DataBuff> .Pop(); if (buff == null) { return; } sendBuffList.Add(buff); copyLen = 2; SerializeUtil.LEMemcpy(buff._data, buff.GetWritePos(), BitConverter.GetBytes(msgType), 0, copyLen); if (_bEncode) { Encode(buff._data, buff.GetWritePos(), copyLen); } buff._dataLen += copyLen; copyLen = 2; SerializeUtil.LEMemcpy(buff._data, buff.GetWritePos(), BitConverter.GetBytes((ushort)dataLen), 0, copyLen); if (_bEncode) { Encode(buff._data, buff.GetWritePos(), copyLen); } buff._dataLen += copyLen; if (data != null) { _sendFileBuff.Clear(); data.Serialize(_sendFileBuff._data, _sendFileBuff.GetWritePos(), FileDataBuff.MAX_FILE_SIZE); while (_sendFileBuff.GetUnreadLen() > 0) { if (buff.GetUnwriteLen() <= 0) { buff = ObjectPool <DataBuff> .Pop(); if (buff == null) { return; } _sendBuffList.Add(buff); } copyLen = Math.Min(buff.GetUnwriteLen(), _sendFileBuff.GetUnreadLen()); SerializeUtil.Memcpy(buff._data, buff.GetWritePos(), _sendFileBuff._data, _sendFileBuff.GetReadPos(), copyLen); if (_bEncode) { Encode(buff._data, buff.GetWritePos(), copyLen); } buff._dataLen += copyLen; _sendFileBuff._readPos += copyLen; } } } else { lock (_sendLocker) { if (_sendBuffList.Count > 0) { int tailIndex = _sendBuffList.Count - 1; sendBuffList.Add(_sendBuffList[tailIndex]); _sendBuffList.RemoveAt(tailIndex); } } bool needNew = sendBuffList.Count <= 0 || (DataBuff.MAX_BUFF_LEN - sendBuffList[sendBuffList.Count - 1]._dataLen < needLen); if (needNew) { buff = ObjectPool <DataBuff> .Pop(); } else { buff = sendBuffList[sendBuffList.Count - 1]; } if (buff != null) { sendBuffList.Add(buff); copyLen = 2; SerializeUtil.LEMemcpy(buff._data, buff.GetWritePos(), BitConverter.GetBytes(msgType), 0, copyLen); if (_bEncode) { Encode(buff._data, buff.GetWritePos(), copyLen); } buff._dataLen += copyLen; copyLen = 2; SerializeUtil.LEMemcpy(buff._data, buff.GetWritePos(), BitConverter.GetBytes((ushort)dataLen), 0, copyLen); if (_bEncode) { Encode(buff._data, buff.GetWritePos(), copyLen); } buff._dataLen += copyLen; if (data != null) { copyLen = data.Serialize(buff._data, buff.GetWritePos(), DataBuff.MAX_BUFF_LEN - buff._dataLen); if (_bEncode) { Encode(buff._data, buff.GetWritePos(), copyLen); } buff._dataLen += copyLen; } } } if (sendBuffList.Count > 0) { lock (_sendLocker) { _sendBuffList.AddRange(sendBuffList); sendBuffList.Clear(); } } if (!IsConnected()) { ClearSendBuffList(); } else { SendBytes(); } }
public FileDataBuff PopRecvData() { if (!IsConnected()) { return(null); } List <DataBuff> recvBuffList = new List <DataBuff>(); lock (_recvLocker) { List <DataBuff> tempList = _recvBuffList; _recvBuffList = recvBuffList; recvBuffList = tempList; } uint copyLen = 0; DataBuff buff = null; while (_recvFileBuff._dataLen < 4) { if (recvBuffList.Count <= 0) { return(null); } buff = recvBuffList[0]; copyLen = Math.Min(4 - _recvFileBuff._dataLen, buff.GetUnreadLen()); SerializeUtil.Memcpy(_recvFileBuff._data, _recvFileBuff.GetWritePos(), buff._data, buff.GetReadPos(), copyLen); buff._readPos += copyLen; _recvFileBuff._dataLen += copyLen; if (buff.GetUnreadLen() <= 0) { buff.Clear(); ObjectPool <DataBuff> .Push(buff); recvBuffList.RemoveAt(0); } } byte[] ushortBytes = new byte[2]; SerializeUtil.LEMemcpy(ushortBytes, 0, _recvFileBuff._data, 2, 2); uint msgLen = BitConverter.ToUInt16(ushortBytes, 0); if (msgLen + 4 > FileDataBuff.MAX_FILE_SIZE) { return(null); } uint needLen = msgLen - (_recvFileBuff._dataLen - 4); while (needLen > 0) { if (recvBuffList.Count <= 0) { return(null); } buff = recvBuffList[0]; copyLen = Math.Min(needLen, buff.GetUnreadLen()); SerializeUtil.Memcpy(_recvFileBuff._data, _recvFileBuff.GetWritePos(), buff._data, buff.GetReadPos(), copyLen); buff._readPos += copyLen; _recvFileBuff._dataLen += copyLen; if (buff.GetUnreadLen() <= 0) { buff.Clear(); ObjectPool <DataBuff> .Push(buff); recvBuffList.RemoveAt(0); } needLen -= copyLen; } if (recvBuffList.Count > 0) { lock (_recvLocker) { recvBuffList.AddRange(_recvBuffList); _recvBuffList.Clear(); _recvBuffList = recvBuffList; } } if (!IsConnected()) { ClearRecvBuffList(); } return(_recvFileBuff); }