c++ - 通过 Boost ASIO 服务器发送缓冲区 - 发送错误数据

标签 c++ arrays boost server boost-asio

谁能告诉我如何将存储在数组中的十六进制值原封不动地发送给客户端?

每当我通过 boost 服务器向客户端发送十六进制字符数组时,它会将其转换为 ASCII/JUNK(无法确定它是什么)。

例如:

我正在尝试发送

"24 bb ff 0f 02 08 01 e0 01 e0 02 08 0f 2d 0f 00 23 61"

通过 Boost asio 服务器在字符数组中。

编辑:

客户端正在接收

"32 34 62 62 66 66 30 66 30 32 30 38 30 31 65 30 30 31 65 30 30 32 30 38 30 66 32 64 30 66 30 30 32 33 36 31"

这是我正在使用的一段代码。

char Sendingdata_[512];
string finalHex = "24bbff0f020801e001e002080f2d0f002361";
strcpy(Sendingdata_, finalHex.c_str());
boost::asio::async_write(socket_, boost::asio::buffer(Sendingdata_,bytes_transferred), boost::bind(&session::handle_write, this, boost::asio::placeholders::error));

我应该使用不同的缓冲区还是任何其他方式来发送十六进制值???

最佳答案

如果代码试图发送超过 37 个字节,那么它将发送未初始化的内存。如果它试图发送超过 512 个字节,那么它正在读取超出缓冲区的末尾。在任何一种情况下,都可能会发送内存垃圾模式。

Sendingdata_ 缓冲区有 512 个字节,但其中只有 37 个字节已被初始化。

char Sendingdata_[512];                 // 512 unitialized values.
std::string finalHex = string-literal;  // 36 ASCII characters + null termination.
strcpy(Sendingdata_, finalHex.c_str()); // 37 characters copied
boost::asio::async_write(..., boost::asio::buffer(Sendingdata_, bytes_transferred), ...);

finalHex 字符串被提供了一个字符串文字。例如,分配一个字符串为 "2400bb" 的字符串文字,将存储 '2''4' '0''0''b''b' ASCII 字符。

std::string ascii = "2400bb";
assert(ascii.length() == 6);
assert('2' == ascii[0]);
assert('4' == ascii[1]);
assert('0' == ascii[2]);
assert('0' == ascii[3]);
assert('b' == ascii[4]);
assert('b' == ascii[5]);

考虑使用 vector ,以十六进制表示法提供数值:

std::vector<unsigned char> hex = { 0x24, 0x00, 0xbb };
assert(hex.size() == 3);
assert(0x24 == hex[0]);
assert(0x00 == hex[1]);
assert(0xbb == hex[2]);

或者,可以通过提供 \x 控制字符来使用 std::string 来指示后续值是十六进制。但是,在解释值时可能需要执行显式转换,并使用处理字符串中空字符的构造函数:

std::string hex("\x24\x00\xbb", 3);
// alternatively: std::string hex{ 0x24, 0x00, static_cast<char>(0xbb) };  
assert(hex.size() == 3);
assert(0x24 == static_cast<unsigned char>(hex[0]));
assert(0x00 == static_cast<unsigned char>(hex[1]));
assert(0xbb == static_cast<unsigned char>(hex[2]));

这是一个例子 demonstrating差异和 Asio 缓冲区的使用:

#include <cassert>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <boost/asio.hpp>

int main()
{
  // String-literial.
  std::string ascii = "2400bb";
  assert(ascii.length() == 6);
  assert('2' == ascii[0]);
  assert('4' == ascii[1]);
  assert('0' == ascii[2]);
  assert('0' == ascii[3]);
  assert('b' == ascii[4]);
  assert('b' == ascii[5]);

  // Verify asio buffers.
  auto ascii_buffer = boost::asio::buffer(ascii);
  assert(ascii.length() == boost::asio::buffer_size(ascii_buffer));
  assert(std::equal(
    boost::asio::buffers_begin(ascii_buffer),
    boost::asio::buffers_end(ascii_buffer),
    std::begin(ascii)));

  // Hex values.
  std::vector<unsigned char> hex = { 0x24, 0x00, 0xbb };
  // alternatively: unsigned char hex[] = { 0x24, 0x00, 0xbb };
  assert(hex.size() == 3);
  assert(0x24 == hex[0]);
  assert(0x00 == hex[1]);
  assert(0xbb == hex[2]);

  // Verify asio buffers.
  auto hex_buffer = boost::asio::buffer(hex);
  assert(hex.size() == boost::asio::buffer_size(hex_buffer));
  assert(std::equal(
    boost::asio::buffers_begin(hex_buffer),
    boost::asio::buffers_end(hex_buffer),
    std::begin(hex),
    std::equal_to<unsigned char>()));

  // String with hex.  As 0x00 is in the string, the string(char*) constructor
  // cannot be used.
  std::string hex2("\x24\x00\xbb", 3);
  // alternatively: std::string hex2{ 0x24, 0x00, static_cast<char>(0xbb) };  
  assert(hex2.size() == 3);
  assert(0x24 == static_cast<unsigned char>(hex2[0]));
  assert(0x00 == static_cast<unsigned char>(hex2[1]));
  assert(0xbb == static_cast<unsigned char>(hex2[2]));
}

关于c++ - 通过 Boost ASIO 服务器发送缓冲区 - 发送错误数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35171361/

相关文章:

c++ - 将 std::string 散列为 std::size_t 以外的东西

c++ - 可以将参数类型转换为 std::min() 吗?

c++ - 通过 QDataStream 序列化 QVariant

c++ - 我可以在 C++11 的类外执行继承吗?

unit-testing - Boost 测试与 Google 测试框架

c++ - 我不明白为什么 boost::asio::read_until 读取定界符后面的字符

c++ - 泛化标准库容器的输出函数

C++:用于循环打印地址而不是值的数组

arrays - 如何避免快速创建对象数组的副本

javascript - 从数组中拆分具有多个分隔符的字符串