• UDP网络通信OSC 协议


    使用方法

    OscMessage mesg;
    mesg.setAddress("m");
    mesg.addIntArg(10);
    mesg.addIntArg(11);
    mesg.addIntArg(12);
    
    g_oscSend.sendMessage(mesg);

    先做记录,再做程序

    整个消息是放在一个数组中

    前8个字符做头   为#bundle

    下面8个字节记录时间  这里都是1, 内存中为 0 0 0 0 0 0 0 1

    再下面4个字节 整数  ,这里的数字大小指的是,osc地址的地址距离数据末尾的字节数 ,(也就是接收到数据包的长度减去这个值,就是osc消息的Adrrs的位置)

    再下面就是地址字符串   大小根据字符串大小 ,然后4个字节对齐,不足补到4的倍数

    再下面是所有参数的类型   第一个是 逗号,不知为何这样,  下面才是类型, 这里如果数量不是4的倍数也要补

    接下来是每个参数的内存

    类型

    enum TypeTagValues {
        TRUE_TYPE_TAG = 'T',
        FALSE_TYPE_TAG = 'F',
        NIL_TYPE_TAG = 'N',
        INFINITUM_TYPE_TAG = 'I',
        INT32_TYPE_TAG = 'i',
        FLOAT_TYPE_TAG = 'f',
        CHAR_TYPE_TAG = 'c',
        RGBA_COLOR_TYPE_TAG = 'r',
        MIDI_MESSAGE_TYPE_TAG = 'm',
        INT64_TYPE_TAG = 'h',
        TIME_TAG_TYPE_TAG = 't',
        DOUBLE_TYPE_TAG = 'd',
        STRING_TYPE_TAG = 's',
        SYMBOL_TYPE_TAG = 'S',
        BLOB_TYPE_TAG = 'b',
        ARRAY_BEGIN_TYPE_TAG = '[',
        ARRAY_END_TYPE_TAG = ']'
    };

    其中  bool  没有内存,只有一个tag

            int32   4个字节

            float  4个字节

            char   4个字节

             int64  8 个字节

             double  8个字节

           timetag   8个字节

           string     补到4的倍数

    2018-4-28 

    找到了一个代码实现

        
    
    enum class ArgType : char { INTEGER_32 = 'i', FLOAT = 'f', DOUBLE = 'd', STRING = 's', BLOB = 'b', MIDI = 'm', TIME_TAG = 't', INTEGER_64 = 'h', BOOL_T = 'T', BOOL_F = 'F', CHAR = 'c', NULL_T = 'N', IMPULSE = 'I', NONE = NULL_T };
    void Bundle::setTimetag( uint64_t ntp_time )
    {
        uint64_t a = htonll( ntp_time );
        ByteArray<8> b;
        memcpy( b.data(), reinterpret_cast<uint8_t*>( &a ), 8 );
        mDataBuffer->insert( mDataBuffer->begin() + 12, b.begin(), b.end() );
    }
        
    void Bundle::initializeBuffer()
    {
        static const std::string id = "#bundle";
        mDataBuffer.reset( new std::vector<uint8_t>( 20 ) );
        std::copy( id.begin(), id.end(), mDataBuffer->begin() + 4 );
        (*mDataBuffer)[19] = 1;
    }
       
        
        size_t addressLen = mAddress.size() + getTrailingZeros( mAddress.size() );
      
        auto typesSize = mDataViews.size() + 1;
        std::vector<char> typesArray( typesSize + getTrailingZeros( typesSize ) , 0 );
        
        typesArray[0] = ',';
        int i = 1;
        for( auto & dataView : mDataViews )
            typesArray[i++] = Argument::translateArgTypeToCharType( dataView.getType() );
        
        if( ! mCache )
            mCache = ByteBufferRef( new ByteBuffer() );
        
        size_t typesArrayLen = typesArray.size();
        ByteArray<4> sizeArray;
        int32_t messageSize = addressLen + typesArrayLen + mDataBuffer.size();
        auto endianSize = htonl( messageSize );
        memcpy( sizeArray.data(), reinterpret_cast<uint8_t*>( &endianSize ), 4 );
        
        mCache->resize( 4 + messageSize );
        
        std::copy( sizeArray.begin(),    sizeArray.end(),    mCache->begin() );
        std::copy( mAddress.begin(),    mAddress.end(),        mCache->begin() + 4 );
        std::copy( typesArray.begin(),    typesArray.end(),    mCache->begin() + 4 + addressLen );
        std::copy( mDataBuffer.begin(),    mDataBuffer.end(),    mCache->begin() + 4 + addressLen + typesArrayLen );
        
       
        auto dataPtr = mCache->data() + 4 + addressLen + typesArrayLen;
        for( auto & dataView : mDataViews ) {
            if( dataView.needsEndianSwapForTransmit() )
                dataView.swapEndianForTransmit( dataPtr );
        }
    static uint8_t getTrailingZeros( size_t bufferSize ) { return 4 - ( bufferSize % 4 ); }

    和我之前的解释一样,现在这个可以照着自己解析了

  • 相关阅读:
    Silverlight“.NET研究” 2.5D RPG游戏技巧与特效处理:(七)动画特写 狼人:
    Silverlight 2.5D RPG游戏“.NET研究”技巧与特效处理:(六)流光追影 狼人:
    WPF中使用amCh“.NET研究”arts绘制股票K线图 狼人:
    验证.N“.NET研究”ET强命称的思路和实例 狼人:
    ASP.NET“.NET研究”下用URLRewriter重写二级域名 狼人:
    spring初始化在ServletContextListener实现类中获取spring注入对象
    执行原因【菜鸟笔记】Ubuntu系统shellscript中 关于for循环以及declare出错的原因
    jqueryfunctionchrome浏览器不支持 onmouseleave事件的解决
    异步线程C#异步委托的使用
    android删除android拦截短信并删除该条短信
  • 原文地址:https://www.cnblogs.com/dragon2012/p/5889346.html
Copyright © 2020-2023  润新知