以windows IOCP 为例,complete 线程在接收到数据后,应该马上将接收到的数据拷贝到解包缓存,然后立即发起一次新的WSARecv 操作。然后再对解包缓存执行操作,解析出逻辑包。通常的方法是将数据拷贝到一个环形缓冲中,以减少数据的拷贝次数。但在解出一个数据包之后,免不了还要将一个完整的数据包拷贝到另一个包缓存中,再将这个包提交给应用层处理.本文介绍一种,拼包方式,以避免从解包缓存copy数据到逻辑包中. 首先介绍逻辑包的组织结构: //RPacket 数据可跨越多个 buffer class RPacket { friend class Connection; friend class WPacket; public: RPacket(const RPacket &other):m_buf(other.m_buf),m_head(other.m_head),m_len(other.m_len) ,m_readPos(other.m_readPos),m_readBuf(0),m_binBuffer(0),m_binBufferPos( 0) { } ~RPacket() { if(m_binBuffer) delete[] m_binBuffer; } bool _nil() { return m_buf._nil(); } RPacket& operator = (const RPacket &other) { if(this == &other) return *this ; m_head = other.m_head; m_len = other.m_len; m_buf = other.m_buf; m_readPos = other.m_readPos; if(m_binBuffer) { delete[] m_binBuffer; m_binBufferPos = 0; } return *this ; } char ReadChar() { return Read(); } short ReadShort() { return Read(); } long ReadLong() { return Read(); } float ReadFloat() { return Read(); } double ReadDouble() { return Read(); } short ReadCmd() { return *(short *)&m_buf->m_buf[m_head+sizeOfLen]; } const char * ReadString() { unsigned int strLen = (unsigned int)Read(); if(strLen == 0 || m_dataRemain < strLen) { return 0; } unsigned int sizeRemain = m_readBuf->m_bufSize - m_readPos; //当前 buf 还有多少有效数据 char *str; if(sizeRemain >= strLen) { str = &m_readBuf->m_buf[m_readPos]; m_readPos += strLen; } else { if(!m_binBuffer) { m_binBuffer = new char [m_len]; m_binBufferPos = 0; } str = &m_binBuffer[m_binBufferPos]; unsigned int copySize = sizeRemain; memcpy(&m_readBuf->m_buf[m_readPos],&...