打包解包函数分享
int WebsocketProtocol::tryDeframeIncomingPacket( PushFramework::DataBuffer& buffer, PushFramework::IncomingPacket*& pPacket, int& serviceId, unsigned int& nExtractedBytes, ConnectionContext* pContext )
{
if (buffer.GetDataSize() == 0)
return Protocol::eIncompletePacket;
WebsocketConnectionContext* pCxt = (WebsocketConnectionContext*) pContext;
if (pCxt->GetStage() == WebsocketConnectionContext::HandshakeStage)
{
WebsocketHandshakeMessage* pMessage = new WebsocketHandshakeMessage(buffer.GetBuffer(), buffer.GetDataSize());
serviceId = 0;
nExtractedBytes = buffer.GetDataSize();
pPacket = pMessage;
return Protocol::Success;
}
//In the other cases, we should expect a data message :
int nMinExpectedSize = 6;
if (buffer.GetDataSize() < nMinExpectedSize)
return Protocol::eIncompletePacket;
BYTE payloadFlags = buffer.getAt(0);
if( (payloadFlags >> 7) == 0 )
{
return Protocol::eUndefinedFailure;
}
/*
if (payloadFlags != 129)
return Protocol::eUndefinedFailure;
*/
BYTE basicSize = buffer.getAt(1) & 0x7F;
unsigned __int64 payloadSize;
int masksOffset;
if (basicSize <= 125)
{
payloadSize = basicSize;
masksOffset = 2;
}
else if (basicSize == 126)
{
nMinExpectedSize += 2;
if (buffer.GetDataSize() < nMinExpectedSize)
return Protocol::eIncompletePacket;
payloadSize = ntohs( *(u_short*) (buffer.GetBuffer() + 2) );
masksOffset = 4;
}
else if (basicSize == 127)
{
nMinExpectedSize += 8;
if (buffer.GetDataSize() < nMinExpectedSize)
return Protocol::eIncompletePacket;
payloadSize = ntohl( *(u_long*) (buffer.GetBuffer() + 2) );
masksOffset = 10;
}
else
return Protocol::eUndefinedFailure;
nMinExpectedSize += payloadSize;
if (buffer.GetDataSize() < nMinExpectedSize)
return Protocol::eIncompletePacket;
BYTE Len = 4; //掩码的长度
BYTE masks[4];
memcpy(masks, buffer.GetBuffer() + masksOffset, 4);
char* payload = new char[payloadSize + 1];
memcpy(payload, buffer.GetBuffer() + masksOffset + Len, payloadSize);
for (unsigned __int64 i = 0; i < payloadSize; i++) {
payload[i] = (payload[i] ^ masks[i%4]);
}
payload[payloadSize] = ' ';
WebsocketDataMessage* pMessage = new WebsocketDataMessage(payload);
serviceId = 1;
nExtractedBytes = nMinExpectedSize;
pPacket = pMessage;
delete payload;
return Protocol::Success;
}
int WebsocketProtocol::frameOutgoingPacket( PushFramework::OutgoingPacket& packet, PushFramework::DataBuffer& buffer, unsigned int& nWrittenBytes, unsigned int size)
{
WebsocketMessage& message = (WebsocketMessage&) packet;
if (message.GetType() == WebsocketMessage::Handshake)
{
WebsocketHandshakeMessage& handshake = (WebsocketHandshakeMessage&) message;
string strRaw = handshake.Serialize();
if(strRaw.size() > buffer.getRemainingSize())
return Protocol::eInsufficientBuffer;
buffer.Append((char*)strRaw.c_str(), strRaw.size());
nWrittenBytes = strRaw.size();
return Protocol::Success;
}
if (message.GetType() == WebsocketMessage::DataMessage)
{
WebsocketDataMessage& dataMessage = (WebsocketDataMessage&) message;
string strData = dataMessage.GetEncodedData();
Stream stream; //二进制写入
int nSize = strData.size();
if(size != 0)
{
nSize = size;
}
unsigned __int64 payloadSize = nSize;
/*
int expectedSize = payloadSize + 1; //统计包的长度
if(payloadSize <= 125 && payloadSize <= 65535 )
expectedSize += 1;
else if(payloadSize > 125 && payloadSize <= 65535)
expectedSize += 3;
else
expectedSize += 9;
if (expectedSize > buffer.getRemainingSize())
return Protocol::eInsufficientBuffer;
*/
//create the flags byte
unsigned char payloadFlags = 130;//包头:字符串129,二进制130
if(size == 0)
{
payloadFlags = 129;
}
if(size == 0)
{
buffer.WriteByte(payloadFlags);
}
else
{
stream.Write(payloadFlags);
}
int expectedSize = 1; //统计包的长度
//create the length byte
if (payloadSize <= 125)
{
unsigned char basicSize = payloadSize;
if(size == 0)
{
buffer.WriteByte(basicSize);
}
else
{
stream.Write(basicSize);
}
expectedSize += 1;
}
else if (/*payloadSize > 125 &&*/ payloadSize <= 65535)//by byfei 2017/02/20
{
unsigned char basicSize = 126;
unsigned char len[2];
len[0] = ( payloadSize >> 8 ) & 255;
len[1] = ( payloadSize ) & 255;
if(size == 0)
{
buffer.WriteByte(basicSize);
buffer.WriteByte(len[0]);
buffer.WriteByte(len[1]);
}
else
{
stream.Write(basicSize);
stream.Write(len[0]);
stream.Write(len[1]);
}
expectedSize += 3;
}
else
{
unsigned char basicSize = 127;
char len[8];
len[0] = ( payloadSize >> 56 ) & 255;
len[1] = ( payloadSize >> 48 ) & 255;
len[2] = ( payloadSize >> 40 ) & 255;
len[3] = ( payloadSize >> 32 ) & 255;
len[4] = ( payloadSize >> 24 ) & 255;
len[5] = ( payloadSize >> 16 ) & 255;
len[6] = ( payloadSize >> 8 ) & 255;
len[7] = ( payloadSize ) & 255;
if(size == 0)
{
buffer.WriteByte(basicSize);
buffer.Append(len, 8);
}
else
{
stream.Write(basicSize);
stream.WriteBuffer(len, 8);
}
expectedSize += 9;
}
//buffer.Append((char*)strData.c_str(), size);
if(size != 0)
{
buffer.Append(stream.getBuf(), expectedSize);
buffer.Append(dataMessage.getStream().getBuf(),nSize);
}
else
{
buffer.Append((char*)strData.c_str(), nSize);
}
expectedSize = payloadSize + expectedSize; //统计包的长度
nWrittenBytes = expectedSize;
return Protocol::Success;
}
return Protocol::eUndefinedFailure;
}
Google protobuf使用中的小陷阱 点击打开链接
Google Protocol Buffers浅析 点击打开链接