c++ - boost asio检测/避免接收缓冲区溢出

标签 c++ networking boost boost-asio

考虑客户端使用 TCP 和 boost::asio 以“同步模式”(也称为“阻塞”功能)向服务器发送数据。

客户端代码(略过query和io_service部分):

tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket( io_service );
boost::asio::connect( socket, endpoint_iterator );
std::array<char, 1000> buf = { /* some data */ };
size_t n = socket.send( boost::asio::buffer(buf) );

这会将整个缓冲区(1000 字节)发送到连接的机器。

现在是服务器代码:

tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4(), port ) );
tcp::socket socket( io_service );
boost::system::error_code err;
std::array<char, 500> buff;
size_t n = socket.read_some( boost::asio::buffer(buff), err );
std::cout << "err=" << err.message() << '\n';
  • 这是做什么的:客户端通过连接发送 1000 字节,服务器尝试将其存储在 500 字节的缓冲区中。
  • 如我所料:服务器错误状态表明缓冲区太小和/或接收到的数据太多。
  • 我得到的结果:“成功”错误值,并且服务器中的 n=1000。

我在这里错过了什么? ASIO 不能检测缓冲区溢出吗? 我是否应该继续使用其他一些类/函数(也许是流?)

引用资料(1.54,这是我使用的那个):

最佳答案

你严重误解了 TCP。

TCP 是一个字节流。 TCP 流中没有数据包边界。在您关闭套接字之前,所有字节都形成一个流。 (与 UDP 不同)

Boost.Asio 知道这一点。只要stream是开着的,就不能说stream最终会有多大。如果你有一个 500 字节的缓冲区,Boost Asio 可以用(可能是无界的)TCP 流的前 500 个字节填充它。

但是,read_some 只是查看已经可用的内容。在您的情况下,只有 1000 个字节,完全可以预期整个 1000 个字节在您的网卡上可用。那部分没有错误。它只是不适合您的缓冲区,但这在网络端不是问题。

TCP 和 UDP 都没有办法回传接收者期待的是一个较小的数据包。那是应用程序级逻辑,你在应用程序级处理它。例如,HTTP 有 413 Payload Too Large。因此,Boost.Asio 不提供标准机制。

关于c++ - boost asio检测/避免接收缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48805652/

相关文章:

flash - 是否可以在 Flash/ActionScript 中使用 UDP?

c++ - 如果在构造中使用,则自动创建成员

c++ - boost::iterator_facade 和 std::find(...)

c++ - 无法使用 boost asio read() 获取所有数据

networking - 如何在 Clojure (/Java) 中稳健地发出大量并发 HTTPS 请求

c++ - 如何对 QLineEdit 中输入的小数进行乘法运算?

c++ - doxygen 外部变量索引

c++ - UBLAS 矩阵查找单元格的周围值?

c++ - 如何计算16bit到8bit的量化误差?

c++ - 我什么时候应该定义自己的复制构造函数和赋值运算符