从linux套接字读取“varint”

我需要从C / C ++的linux套接字中读取VarInts 。 任何图书馆,想法或东西?

我尝试阅读和铸造字符布尔[8]尝试没有成功阅读VarInt …

此外,这是为了与新的Minecraft 1.7.2通信协议兼容,所以协议的文档也可能有所帮助。

让我解释一下我的项目:我正在制作一个Minecraft服务器软件在我的VPS中运行(因为java太慢了…),我被这个协议困住了。 一个线程等待连接,当它有一个新的连接时,它创build一个新的Client对象并启动开始与客户端通信的客户端线程。

我认为没有必要显示代码。 如果我错了,告诉我,我会编辑一些代码。

首先,请注意,varints作为实际字节发送,而不是字符10字符串。

对于一个无符号的varint,我相信下面的代码将会为你解码,假设你已经在数据指向的缓冲区中获得了varint data 。 此示例函数返回参考参数int decoded_bytes解码的字节数。

 uint64_t decode_unsigned_varint( const uint8_t *const data, int &decoded_bytes ) { int i = 0; uint64_t decoded_value = 0; int shift_amount = 0; do { decoded_value |= (uint64_t)(data[i] & 0x7F) << shift_amount; shift_amount += 7; } while ( (data[i++] & 0x80) != 0 ); decoded_bytes = i; return decoded_value; } 

要解码已签名的varint,可以使用第二个调用第一个的函数:

 int64_t decode_signed_varint( const uint8_t *const data, int &decoded_bytes ) { uint64_t unsigned_value = decode_unsigned_varint(data, decoded_bytes); return (int64_t)( unsigned_value & 1 ? ~(unsigned_value >> 1) : (unsigned_value >> 1) ); } 

我相信这两个功能都是正确的。 我使用下面的代码做了一些基本的测试,以验证Google页面中的几个数据点。 输出是正确的。

 #include <stdint.h> #include <iostream> uint64_t decode_unsigned_varint( const uint8_t *const data, int &decoded_bytes ) { int i = 0; uint64_t decoded_value = 0; int shift_amount = 0; do { decoded_value |= (uint64_t)(data[i] & 0x7F) << shift_amount; shift_amount += 7; } while ( (data[i++] & 0x80) != 0 ); decoded_bytes = i; return decoded_value; } int64_t decode_signed_varint( const uint8_t *const data, int &decoded_bytes ) { uint64_t unsigned_value = decode_unsigned_varint(data, decoded_bytes); return (int64_t)( unsigned_value & 1 ? ~(unsigned_value >> 1) : (unsigned_value >> 1) ); } uint8_t ex_p300[] = { 0xAC, 0x02 }; uint8_t ex_n1 [] = { 0x01 }; using namespace std; int main() { int decoded_bytes_p300; uint64_t p300; p300 = decode_unsigned_varint( ex_p300, decoded_bytes_p300 ); int decoded_bytes_n1; int64_t n1; n1 = decode_signed_varint( ex_n1, decoded_bytes_n1 ); cout << "p300 = " << p300 << " decoded_bytes_p300 = " << decoded_bytes_p300 << endl; cout << "n1 = " << n1 << " decoded_bytes_n1 = " << decoded_bytes_n1 << endl; return 0; } 

要编码varints,可以使用以下功能。 请注意,缓冲区uint8_t *const data应该至少有10个字节的空间,因为最大的varint长度是10个字节。
#包括

 // Encode an unsigned 64-bit varint. Returns number of encoded bytes. // 'buffer' must have room for up to 10 bytes. int encode_unsigned_varint(uint8_t *const buffer, uint64_t value) { int encoded = 0; do { uint8_t next_byte = value & 0x7F; value >>= 7; if (value) next_byte |= 0x80; buffer[encoded++] = next_byte; } while (value); return encoded; } // Encode a signed 64-bit varint. Works by first zig-zag transforming // signed value into an unsigned value, and then reusing the unsigned // encoder. 'buffer' must have room for up to 10 bytes. int encode_signed_varint(uint8_t *const buffer, int64_t value) { uint64_t uvalue; uvalue = uint64_t( value < 0 ? ~(value << 1) : (value << 1) ); return encode_unsigned_varint( buffer, uvalue ); }