/// <summary> /// 将待发送数据提取拷贝到待发送的buffer中,其中sendCount为可写的长度。这是为了拼接多条消息一起发送。 /// </summary> /// <param name="sendBuff">要写入的发送buffer</param> /// <param name="sendBuffOffset">发送buffer的起始偏移</param> /// <param name="sendCount">期望的可发送长度(byte单位)</param> /// <returns>实际写入发送的长度(byte单位)</returns> public int WriteSendDataToBuffer(byte[] sendBuff, int sendBuffOffset, int sendCount) { if (sendBuff == null || sendBuffOffset + sendCount > sendBuff.Length) { throw new Exception("WriteSendDataToBuffer():sendBuff == null || sendBuffOffset + sendCount > sendBuff.Length"); } if (_queueSendData.Count == 0) { return(0); } int copyedLength = 0; _queueSendData.LockEnter(); while (true) { if (_queueSendData.Count == 0) { break; } if (sendCount == 0) { break; } IntPtr ipMsgItem = _queueSendData._queue.Peek(); MsgItem *msgItem = (MsgItem *)ipMsgItem.ToPointer(); //得到当前的消息 int copyLen = msgItem->length - msgItem->index; if (copyLen < sendCount) //这一整条消息都能写下 { //IntPtr p = Marshal.UnsafeAddrOfPinnedArrayElement(sendBuff, sendBuffOffset); Marshal.Copy(msgItem->getCurCopyPtr(), sendBuff, sendBuffOffset, copyLen); _queueSendData._queue.Dequeue(); //退出这一条 Marshal.FreeHGlobal(msgItem->msg); //释放这条 Marshal.FreeHGlobal(ipMsgItem); copyedLength += copyLen; sendBuffOffset += copyLen; sendCount -= copyLen; } else//如果这一条消息整个sendBuff都写不下 { copyLen = sendCount;//那么使用最大长度为它的要发送的长度 Marshal.Copy(msgItem->getCurCopyPtr(), sendBuff, sendBuffOffset, copyLen); msgItem->index += copyLen; copyedLength += copyLen; break;//那么也可以直接退出了 } } _queueSendData.LockExit(); return(copyedLength); }
/// <summary> /// 用户添加一段要发送的数据进来 /// </summary> /// <param name="data">数据</param> /// <param name="offset">偏移</param> /// <param name="count">计数</param> public void AddSend(byte[] data, int offset, int count) { IntPtr msg = Marshal.AllocHGlobal(sizeof(int) + count); int * p = (int *)msg.ToPointer(); p[0] = count;//消息首写一个包长度 IntPtr dataPtr = new IntPtr(&p[1]); Marshal.Copy(data, offset, dataPtr, count); //item的长度是整个消息的长度,所以保函了前面的sizeof(int) IntPtr ipitem = Marshal.AllocHGlobal(sizeof(MsgItem)); MsgItem *item = (MsgItem *)ipitem.ToPointer(); item->msg = msg; item->index = 0; item->length = sizeof(int) + count; _queueSendData.Enqueue(ipitem); }
/// <summary> /// 当前重启的时候用来清空内部数据 /// </summary> public void Clear() { _queueSendData.LockEnter(); while (_queueSendData._queue.Count > 0) { IntPtr ipMsgItem = _queueSendData._queue.Dequeue(); //退出这一条 MsgItem *msgItem = (MsgItem *)ipMsgItem.ToPointer(); //得到当前的消息 Marshal.FreeHGlobal(msgItem->msg); //释放这条 Marshal.FreeHGlobal(ipMsgItem); } _queueSendData.LockExit(); _queueReceMsg.LockEnter(); while (_queueReceMsg._queue.Count > 0) { ByteBuffer bf = _queueReceMsg._queue.Dequeue(); bf.Recycle();//回收这一条 } _queueReceMsg.LockExit(); ClearTempLastMsg(); }