zoukankan      html  css  js  c++  java
  • [手游新项目历程]第9天-webSocket 包头:字符串129,二进制130

    打包解包函数分享

    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浅析 点击打开链接

  • 相关阅读:
    sql server中的左连接与右连接的简便写法
    SQL中CONVERT()转化函数的用法 字符串转日期
    Asp.net MVC 中Controller返回值类型ActionResult
    一探前端开发中的JS调试技巧
    String trim 坑 对于ascii码为160的去不掉
    SQL小练习
    Java运行时异常和非运行时异常
    java 子类不能继承父类的static方法
    Java中的类加载器
    搞懂head 和 tail 命令
  • 原文地址:https://www.cnblogs.com/byfei/p/14104299.html
Copyright © 2011-2022 走看看