【问题标题】:boost asio cross platform newline confusion提升 asio 跨平台换行混淆
【发布时间】:2014-04-09 18:30:21
【问题描述】:

我正在使用 boost asio 编写简单的服务器/客户端来传输二进制数据。特别是,我将 async_write 和 async_read 与 ip:tcp::socket 一起使用。没什么特别的,真的。

boost::asio::async_write(*mp_socket, boost::asio::buffer(data_ptr, data_size), 
                         boost::bind(&TcpSocket::m_handleWrite, this,
                                     boost::asio::placeholders::error,
                                     boost::asio::placeholders::bytes_transferred));

boost::asio::async_read(*mp_socket, boost::asio::buffer(mp_buffer, m_buffer_size),
                         boost::bind(&TcpSocket::m_handleRead, this,
                                     boost::asio::placeholders::error,
                                     boost::asio::placeholders::bytes_transferred));

我随机生成二进制数据并在各种平台对中发送/接收以进行测试。该代码在同一平台上运行良好(如全部在linux,全部在windows),但无法跨平台运行。

比如左边是windows中接收的数据,右边是linux中发送的数据。唯一的区别是 Windows 中的 0D0A (CRLF) 和 linux 中的 0A (LF)。我认为某处(在 boost asio 或 winsock 等中),正在发生 LF->CRLF 转换。

那么,当我发送二进制数据时,有没有办法禁用转换?我在 boost::asio 配置中寻找一些选项(例如使用原始缓冲区,而不是流缓冲区),但找不到它。谢谢你的帮助。


data_ptr 中的数据

  size_t sz = rand() % 60000;
  char* p = (char*)malloc(sz + 4);
  uint32_t* p_header = reinterpret_cast<uint32_t*>(p);
  *p_header = htonl((uint32_t)sz);
  for (size_t i = 0; i < sz; ++i)
  {
    p[i + 4] = rand() % 255;
  }

【问题讨论】:

  • 通常您提供的缓冲区不会被async_writeasync_read 调用修改(采用ConstBufferSequence 的重载应该 保证这一点)。差异可能发生在缓冲区本身生成的地方。你能显示那个代码吗?
  • 您好,Chad,您能否再澄清一下这个问题?您指的是哪个“缓冲区”? boost::asio::buffer,还是 char* mp_buffer,还是随机填充值的数据缓冲区?
  • 如何生成data_ptr的内容?

标签: c++ newline boost-asio


【解决方案1】:

我认为这个问题是因为async_read 是“面向流的”,请参阅:Short reads and writes

我假设asio 分别使用CRLFLF 作为 Windows 和 Linux 中的流终止符,我猜想它在某处使用 Windows 终止符作为 Linux 流,反之亦然。

尝试将您的 async_read 呼叫更改为:

mp_socket->async_read_some(boost::asio::buffer(mp_buffer, m_buffer_size),
                           boost::bind(&TcpSocket::m_handleRead, this,
                                       boost::asio::placeholders::error,
                                       boost::asio::placeholders::bytes_transferred));

我已使用此方法读取大型二进制文件,并根据其哈希验证接收到的文件,没有遇到您遇到的任何问题。

【讨论】:

    猜你喜欢
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多