将unsigned int +字符串转换为unsigned char向量 [英] Casting an unsigned int + a string to an unsigned char vector

查看:184
本文介绍了将unsigned int +字符串转换为unsigned char向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用NetLink套接字库( https://sourceforge.net/apps/wordpress / netlinksockets / ),并且我想通过网络以我指定的格式发送一些二进制数据。

I'm working with the NetLink socket library ( https://sourceforge.net/apps/wordpress/netlinksockets/ ), and I want to send some binary data over the network in a format that I specify.

我计划的格式很简单并且如下:

The format I have planned is pretty simple and is as follows:


  • 字节0和1:类型uint16_t的操作码(即,无符号整数总是2字节长)

  • Bytes 0 and 1: an opcode of the type uint16_t (i.e., an unsigned integer always 2 bytes long)

字节2以上:任何其他必要的数据,如字符串,整数,每个的组合等。这个数据根据操作码。例如,如果操作码为0,表示登录,则该数据将由一个字节整数组成,告诉您用户名有多长,其后是包含用户名的字符串,后跟包含密码的字符串。对于操作码1发送聊天消息,这里的整个数据可以仅是聊天消息的字符串。

Bytes 2 onward: any other data necessary, such as a string, an integer, a combination of each, etc.. the other party will interpret this data according to the opcode. For example, if the opcode is 0 which represents "log in", this data will consist of one byte integer telling you how long the username is, followed by a string containing the username, followed by a string containing the password. For opcode 1, "send a chat message", the entire data here could be just a string for the chat message.

这里是库给我使用发送数据,但是:

Here's what the library gives me to work with for sending data, though:

void send(const string& data);
void send(const char* data);
void rawSend(const vector<unsigned char>* data);

我假设我想使用rawSend()这个..但rawSend chars,not a void * pointer to memory?如果我试图将某些类型的数据转换为unsigned chars数组,这里是不会有一些数据丢失?请纠正我,如果我错了..但如果我是对的,这是否意味着我应该看另一个图书馆,支持真正的二进制数据传输?

I'm assuming I want to use rawSend() for this.. but rawSend() takes unsigned chars, not a void* pointer to memory? Isn't there going to be some loss of data here if I try to cast certain types of data to an array of unsigned chars? Please correct me if I'm wrong.. but if I'm right, does this mean I should be looking at another library that has support for real binary data transfer?

假设这个库确实服务于我的目的,我将如何转换和连接我的各种数据类型到一个std :: vector?我试过的是这样的:

Assuming this library does serve my purposes, how exactly would I cast and concatenate my various data types into one std::vector? What I've tried is something like this:

#define OPCODE_LOGINREQUEST 0

std::vector<unsigned char>* loginRequestData = new std::vector<unsigned char>();
uint16_t opcode = OPCODE_LOGINREQUEST;
loginRequestData->push_back(opcode);
// and at this point (not shown), I would push_back() the individual characters of the strings of the username and password.. after one byte worth of integer telling you how many characters long the username is (so you know when the username stops and the password begins)
socket->rawSend(loginRequestData);

有些例外,但另一方面,当我试图解释数据。我接近铸件都错了吗?

Ran into some exceptions, though, on the other end when I tried to interpret the data. Am I approaching the casting all wrong? Am I going to lose data by casting to unsigned chars?

提前感谢。

推荐答案

我喜欢他们如何让你创建一个向量(必须使用堆,因此在不可预测的时间执行),而不是只是回到C标准 (const void * buffer,size_t len)元组,它与全部兼容,并且不能被打败。

I like how they make you create a vector (which must use the heap and thus execute in unpredictable time) instead of just falling back to the C standard (const void* buffer, size_t len) tuple, which is compatible with everything and can't be beat for performance. Oh, well.

您可以尝试:

void send_message(uint16_t opcode, const void* rawData, size_t rawDataSize)
{
    vector<unsigned char> buffer;
    buffer.reserve(sizeof(uint16_t) + rawDataSize);
#if BIG_ENDIAN_OPCODE
    buffer.push_back(opcode >> 8);
    buffer.push_back(opcode & 0xFF);
#elseif LITTLE_ENDIAN_OPCODE
    buffer.push_back(opcode & 0xFF);
    buffer.push_back(opcode >> 8);
#else
    // Native order opcode
    buffer.insert(buffer.end(), reinterpret_cast<const unsigned char*>(&opcode), 
        reinterpret_cast<const unsigned char*>(&opcode) + sizeof(uint16_t));
#endif
    const unsigned char* base(reinterpret_cast<const unsigned char*>(rawData));
    buffer.insert(buffer.end(), base, base + rawDataSize);
    socket->rawSend(&buffer); // Why isn't this API using a reference?!
}

这使用 insert 这应优于用 push_back()的手写循环。如果 rawSend 抛出异常,它也不会泄露缓冲区。

This uses insert which should optimize better than a hand-written loop with push_back(). It also won't leak the buffer if rawSend tosses an exception.

注意:字节顺序必须与此连接两端的平台匹配。如果没有,你需要选择一个字节顺序并坚持下去(互联网标准通常这样做,你使用 htonl htons 函数),或者你需要检测字节顺序(从接收者的POV的本地或向后),如果向后,修复它。

NOTE: Byte order must match for the platforms on both ends of this connection. If it does not, you'll need to either pick one byte order and stick with it (Internet standards usually do this, and you use the htonl and htons functions) or you need to detect byte order ("native" or "backwards" from the receiver's POV) and fix it if "backwards".

这篇关于将unsigned int +字符串转换为unsigned char向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆