C++ TCP客户端无法使用read读取所有数据
我有TCP客户端和服务器在同一台机器上运行。两者都以同步阻塞模式运行。连接和验收工作正常 服务器:C++ TCP客户端无法使用read读取所有数据,c++,sockets,boost,tcp,C++,Sockets,Boost,Tcp,我有TCP客户端和服务器在同一台机器上运行。两者都以同步阻塞模式运行。连接和验收工作正常 服务器: socket = std::make_unique<boost::asio::ip::tcp::socket>(*io_service); acceptor_ = std::make_unique<boost::asio::ip::tcp::acceptor>( *io_service, boost::asio::ip::tcp::endpoint(boos
socket = std::make_unique<boost::asio::ip::tcp::socket>(*io_service);
acceptor_ = std::make_unique<boost::asio::ip::tcp::acceptor>(
*io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),
port));
boost::system::error_code error_code;
acceptor_->accept(*socket, error_code);
if (error_code) return error_code;
// Initialize |buffer|.
// write 1
socket->write_some(
boost::asio::buffer(buffer.data(), buffer.size()), error_code);
if (error_code) {
return error_code;
}
auto data = GetData();
// Size of data is 722 bytes.
// write 2
socket->write_some(
boost::asio::buffer(data.data(), data.size()),
error_code);
socket=std::使_唯一(*io_服务);
接受者=std::使_唯一(
*io_服务,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),
港口);;
boost::system::error\u code error\u code;
接受程序->接受(*套接字,错误代码);
if(error_code)返回error_code;
//初始化缓冲区。
//写1
套接字->写一些(
boost::asio::buffer(buffer.data(),buffer.size()),错误代码);
如果(错误代码){
返回错误代码;
}
自动数据=GetData();
//数据大小为722字节。
//写2
套接字->写一些(
boost::asio::buffer(data.data(),data.size()),
错误代码);
客户:
auto socket = std::make_unique<boost::asio::ip::tcp::socket>(*io_service);
boost::asio::ip::tcp::endpoint endpoint(
boost::asio::ip::address_v4::from_string(ip), port);
boost::system::error_code error_code;
socket->connect(endpoint, error_code);
if (error_code) {
return error_code;
}
// This data won't be read from server.
socket->write_some(boost::asio::buffer(buffer.data(), buffer.size()),
error_code);
// Read from write 1
boost::asio::streambuf buffer1;
boost::asio::read(*socket, buffer, boost::asio::transfer_at_least(8),
error_code);
buffer1.consume(8);
// Read from write 2
// Extract length from buffer1. |len_bytes|
boost::asio::read(*socket,
buffer1,
boost::asio::transfer_at_least(len_bytes),
error_code);
auto socket=std::使_唯一(*io_服务);
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address_v4::from_字符串(ip),端口);
boost::system::error\u code error\u code;
套接字->连接(端点,错误代码);
如果(错误代码){
返回错误代码;
}
//无法从服务器读取此数据。
socket->write_some(boost::asio::buffer(buffer.data(),buffer.size()),
错误代码);
//读写1
boost::asio::streambuf buffer1;
boost::asio::read(*套接字、缓冲区、boost::asio::transfer_至少(8),
错误代码);
1.消费(8);
//读写2
//从buffer1中提取长度|len_字节|
boost::asio::read(*socket,
缓冲区1,
boost::asio::至少传输(len_字节),
错误代码);
以读代写1工作正常。但是,如果我在完成处理程序中指定722字节,则write 2将写入722字节并读取2个块。
如果我在读取2之前调用socket->available(error\u code)
,它会给出218。
如果我重复写2,我得到722+218字节。我也试着把sleep()。
这里出了什么问题?在error\u code
中没有提示?@user4581301没有。一切都是成功的。不知道这里是否是这种情况,但TCP新手通常认为,因为发送方在一次调用send()
,发送了N个字节,这意味着接收方将在一次调用recv()
中接收N个字节;然而,这不是一个有效的假设。由于TCP是一种流协议,recv()
返回的“块大小”不一定等于先前传递给send()
的数据量,因此,例如,如果发送718字节,接收器可能会读取多个较小的数据量(最终总计718字节)但不一定一次接收718字节。TCP或ASIO-land中没有人知道写入1和写入2之间有任何区别。它们几乎肯定会被塞进同一个包里。Read 1将读取至少8个字节,但除非我误读了文档,否则我的ASIO fu很弱,将达到缓冲区的长度。当前完成条件为“至少”,如“不少于8,但如果有更多…”transfer\u all
看起来不是正确的解决方案,除非您再创建一个大小为8的缓冲区,而且我没有看到一个transfer\u确切地
。