处理 C/C++ 中的十六进制值
我使用 winsock 从网络上的另一台计算机接收值。它是一个 TCP 套接字,消息的前 4 个字节携带其大小。消息的其余部分由服务器使用 protobuf(来自 google 的协议缓冲区)进行格式化。
我认为,问题在于服务器发送的值似乎是作为 char 发送的十六进制值(即 0x10 只收到 10)。为了接收这些值,我这样做:
bytesreceived = recv(sock, buffer, msg_size, 0);
for (int i=0;i<bytesreceived;i++)
{
data_s << hex << buffer[i];
}
其中 data_s 是字符串流。我可以使用 protobuf 中的 ParseFromIstream(&data_s) 方法并恢复我想要的信息。
我遇到的问题是,这非常非常长(我使用 QSock 得到了另一个实现,我不能将其用于我的项目,但速度要快得多,因此服务器端没有问题)。
我尝试了从这里和互联网上的任何地方获取的许多东西(使用字节数组、字符串),但没有任何效果。
我还有其他选择吗?
感谢您的时间和评论;)
I receive values using winsock from another computer on the network. It is a TCP socket, with the 4 first bytes of the message carrying its size. The rest of the message is formatted by the server using protobuf (protocol buffers from google).
The problemn, I think, is that it seems that the values sent by the server are hex values sent as char (ie only 10 received for 0x10). To receive the values, I do this :
bytesreceived = recv(sock, buffer, msg_size, 0);
for (int i=0;i<bytesreceived;i++)
{
data_s << hex << buffer[i];
}
where data_s is a stringstream. Them I can use the ParseFromIstream(&data_s) method from protobuf and recover the information I want.
The problem that I have is that this is VERY VERY long (I got another implementation using QSock taht I can't use for my project but which is much faster, so there is no problem on the server side).
I tried many things that I took from here and everywhere on the internet (using Arrays of bytes, strings), but nothing works.
Do I have any other options ?
Thank you for your time and comments ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不确定这是否有任何用处,但我之前使用过类似的协议(前 4 个字节保存一个带有长度的 int,其余部分使用 protobuf 进行编码)并对其进行解码,我做了类似的事情(可能不是最由于附加到字符串而有效的解决方案):
not sure if this will be of any use, but I've used a similar protocol before (first 4 bytes holds an int with the length, rest is encoded using protobuf) and to decode it I did something like this (probably not the most efficient solution due to appending to strings):
我不会使用流运算符。它们用于格式化数据,但这不是您想要的。
您可以将接收到的值保存在 char 类型(字节向量)的 std::vector 中。这本质上只是一个动态数组。如果你想继续使用字符串流,你可以使用 stringstream::write 函数,它需要一个缓冲区和一个长度。您应该拥有从调用 recv 时收到的缓冲区和字节数。
如果你想使用向量方法,你可以使用std::copy来使它更容易。
I wouldn't use the stream operators. They're for formatted data and that's not what you want.
You can keep the values received in a std::vector with the char type (vector of bytes). That would essentially just be a dynamic array. If you want to continue using a string stream, you can use the stringstream::write function which takes a buffer and a length. You should have the buffer and number of bytes received from your call to recv.
If you want to use the vector method, you can use std::copy to make it easier.
你的问题有点模棱两可。让我们以你的例子为例。您收到字符形式的
10
,并且希望将其检索为十六进制数字。假设
recv
会给你这个字符串,你可以这样做。首先使其以 null 终止:
然后您可以使用字符串的标准 *scanf 函数非常轻松地从此缓冲区读取值:
就这样!
编辑:如果您收到相反顺序的数字(例如
01
代表10
),那么最好的办法可能是手动转换它:但这只是一个明显的例子。实际上,您可以通过位移来实现,而不是乘法。
Your question is kind of ambiguous. Let's follow your example. You receive
10
as characters and you want to retrieve this as a hex number.Assuming
recv
will give you this character string, you can do this.First of all make it null terminated:
then you can very easily read the value from this buffer using standard *scanf function for strings:
There you go!
Edit: If you receive the number in reverse order (so
01
for10
), probably your best shot is to convert it manually:This is just a clear example though. In reality you would do it with bit shifting for example rather than multiplying.
buffer
是什么数据类型?整个事情看起来像是一个很大的空操作,因为
operator<<(stringstream&, char)
忽略了基本说明符。hex
说明符仅影响非字符整型类型的格式。当然,您不想将文本数据传递给 protobuf。只需将
buffer
指针交给 protobuf,就完成了。What data type is
buffer
?The whole thing looks like a great big no-op, since
operator<<(stringstream&, char)
ignores the base specifier. Thehex
specifier only affects formatting of non-character integral types. For certain you don't want to be handing textual data to protobuf.Just hand the
buffer
pointer to protobuf, you're done.好吧,大胆猜测一下:假设您的入口流是
"71F4E81DA..."
,并且您希望将其转换为字节流{ 0x71, 0xF4, 0xE8, .. .}
。然后我们可以从字符文字中组装字节,如下所示,示意性地:这里我们使用一个小辅助函数:
OK, a shot into the dark: Let's say your ingress stream is
"71F4E81DA..."
, and you want to turn this into a byte stream{ 0x71, 0xF4, 0xE8, ...}
. Then we can just assemble the bytes from the character literals as follows, schematically:Here we use a little helper function: