考虑客户端使用TCP将数据发送到服务器,使用boost :: asio,以“同步模式”(又称“阻塞”功能)。
客户端代码(跳过有关查询和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';
我在这里想念什么? ASIO不能检测缓冲区溢出吗? 我应该继续使用其他一些类/功能(流,也许?)
参考(1.54,我使用的那个):
答案 0 :(得分:1)
你严重误解了TCP。
TCP是一个字节流。 TCP流中没有数据包边界。在关闭套接字之前,所有字节都形成一个流。 (与UDP不同)
Boost.Asio知道这一点。只要流是开放的,它就不能说流最终会有多大。如果你有一个500字节的缓冲区,Boost Asio可以用(可能无界的)TCP流的前500字节填充它。
但是,read_some
只关注已有的内容。在您的情况下,只需1000个字节,完全可以预期您的网卡上可以使用整个1000个字节。该部分没有错误。它不适合你的缓冲区,但这在网络方面不是问题。
TCP和UDP都没有办法回传接收器期望更小的数据包。这是应用程序级逻辑,您可以在应用程序级别处理它。例如,HTTP具有413 Payload Too Large
。因此,Boost.Asio并没有提供标准机制。
答案 1 :(得分:0)
您确实收到了500个字节,并且可以通过再次调用asio来读取最后500个字节。只是这样说,因为在我看来你误解了asio的行为。