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

  • 相关阅读:
    Web API 强势入门指南
    毫秒必争,前端网页性能最佳实践
    Windbg Extension NetExt 使用指南 【3】 ---- 挖掘你想要的数据 Managed Heap
    Windbg Extension NetExt 使用指南 【2】 ---- NetExt 的基本命令介绍
    Windbg Extension NetExt 使用指南 【1】 ---- NetExt 介绍
    WCF : 修复 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service 问题
    透过WinDBG的视角看String
    Microsoft Azure Web Sites应用与实践【4】—— Microsoft Azure网站的“后门”
    企业IT管理员IE11升级指南【17】—— F12 开发者工具
    WCF : 如何将NetTcpBinding寄宿在IIS7上
  • 原文地址:https://www.cnblogs.com/byfei/p/14104299.html
Copyright © 2011-2022 走看看