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 ); }

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

原文地址:https://www.cnblogs.com/dragon2012/p/5889346.html