gpt4 book ai didi

c++ - 从 linux 套接字读取 "varint"

转载 作者:IT王子 更新时间:2023-10-29 01:07:34 26 4
gpt4 key购买 nike

我需要阅读 VarInts来自 C/C++ 中的 linux 套接字。任何图书馆、想法或其他东西?

我尝试读取并将 char 转换为 bool[8] 以尝试读取 VarInt 但没有成功...

此外,这是为了与新的 Minecraft 1.7.2 通信协议(protocol)兼容,因此,the documentation of the protocol也可能有所帮助。

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

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

最佳答案

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

对于未签名的 varint,我相信下面会为您解码它,假设您已经在 data 指向的缓冲区中获得了 varint 数据。此示例函数返回引用参数 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;
}

要对 varint 进行编码,您可以使用以下函数。请注意,缓冲区 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 );
}

关于c++ - 从 linux 套接字读取 "varint",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19758270/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com