boost :: Asio写作大小的悬挂
boost::asio write hangs for large sizes
我正在使用boost :: asio实现TCP服务器和客户端。当文件的大小很大时,我正在使用写入和读取函数,而写入悬挂且未完成。
这是读取
的函数int send_request(std::string &ep_ip, int ep_port, std::string &message, std::string &response) {
boost::asio::io_service io_service;
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(ep_ip), ep_port);
try {
boost::asio::ip::tcp::socket socket(io_service);
boost::system::error_code error;
socket.connect(ep);
std::vector<char> buf(BUF_SIZE);
// buf = new std::vector<char>(BUF_SIZE);
std::copy(message.begin(), message.end(), buf.begin());
boost::asio::write(socket, boost::asio::buffer(buf), error);
// int bytes_read = socket.read_some(boost::asio::buffer(buf) , error );
int bytes_read = boost::asio::read(socket, boost::asio::buffer(buf), error);
std::copy(buf.begin(), buf.begin() + bytes_read, std::back_inserter(response));
socket.close();
} catch (std::exception &e) {
// std::cerr << e.what() << std::endl;
return 0;
}
return 1;
}
这是写入
的函数void listen(int port_no, std::string &filename) {
boost::asio::io_service io_service;
std::string result = "";
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_no));
while (1) {
tcp::socket socket(io_service);
std::vector<char> buf(BUF_SIZE);
boost::system::error_code ignored_error, error;
acceptor.accept(socket);
int req_bytes_read = socket.read_some(boost::asio::buffer(buf), error);
std::string request;
std::copy(buf.begin(), buf.begin() + req_bytes_read, std::back_inserter(request));
request = clean_string(request);
if (error) {
std::cout << "[ERROR] Unable to process the request. CODE " << error << std::endl;
} else {
std::cout << "Received the message: " << request << std::endl;
// This where we do some processing of the request, perhaps call grep.
std::string PATH = "$HOME/" + filename;
result = "";
grep_impl(request, PATH, result);
// result = grep(request , PATH);
}
std::cout << "Size of result is " << result.size() << std::endl;
boost::asio::write(socket, boost::asio::buffer(result), ignored_error);
socket.close();
}
}
所以grep_impl在结果中放了一个大字符串。精确的38MB - Rahul Mahadev 18小时前
因此,在回应该评论时:您只阅读BUF_SIZE
字符。
(请注意,这仍然不会导致写信,因为写操作只会在连接通过对等重置时停止,您在send_request
客户端中有一个明确的socket.close()
)。 <</em>
读取更大的响应(我假设38MB更大)您需要一个循环。
while (!error) {
int bytes_read = ba::read(socket, ba::buffer(buf), error);
std::copy(buf.begin(), buf.begin() + bytes_read, std::back_inserter(response));
if (bytes_read == 0)
break;
}
当服务器停止传输时,您可以期望错误通常成为eof
。
您在
buf
中发送了所有字节,即使是未填充的字节。我不确定这是故意的,但至少它正在破坏输出。哦。也许是
clean_string
是这样做的,但是为什么不简单地仅发送请求?
这是一个独立的演示,使用1K缓冲区传输38MB数据:
活在coliru
#include <boost/asio.hpp>
#include <iostream>
static constexpr size_t BUF_SIZE = 1024u;
namespace ba = boost::asio;
using ba::ip::tcp;
int send_request(std::string const& ep_ip, int ep_port, std::string const& message, std::string &response) {
ba::io_service io_service;
tcp::endpoint ep(ba::ip::address::from_string(ep_ip), ep_port);
try {
tcp::socket socket(io_service);
boost::system::error_code error;
socket.connect(ep);
std::vector<char> buf(BUF_SIZE);
std::copy(message.begin(), message.end(), buf.begin());
ba::write(socket, ba::buffer(buf), error);
// int bytes_read = socket.read_some(ba::buffer(buf) , error );
while (!error) {
int bytes_read = ba::read(socket, ba::buffer(buf), error);
std::copy(buf.begin(), buf.begin() + bytes_read, std::back_inserter(response));
if (bytes_read == 0)
break;
}
socket.close();
} catch (std::exception &e) {
// std::cerr << e.what() << std::endl;
return 0;
}
return 1;
}
std::string clean_string(std::string const& s) {
return s.c_str(); // Cut from NUL
}
void grep_impl(std::string const& /*request*/, std::string const& /*PATH*/, std::string& result) {
result = std::string(38ul << 20, '*');
}
void listen(int port_no, std::string const& filename) {
ba::io_service io_service;
std::string result = "";
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_no));
while (1) {
tcp::socket socket(io_service);
std::vector<char> buf(BUF_SIZE);
boost::system::error_code ignored_error, error;
acceptor.accept(socket);
int req_bytes_read = socket.read_some(ba::buffer(buf), error);
std::string request;
std::copy(buf.begin(), buf.begin() + req_bytes_read, std::back_inserter(request));
request = clean_string(request);
if (error) {
std::cout << "[ERROR] Unable to process the request. CODE " << error << std::endl;
} else {
std::cout << "Received the message: " << request << std::endl;
// This where we do some processing of the request, perhaps call grep.
std::string PATH = "$HOME/" + filename;
result = "";
grep_impl(request, PATH, result);
// result = grep(request , PATH);
}
std::cout << "Size of result is " << result.size() << std::endl;
ba::write(socket, ba::buffer(result), ignored_error);
socket.close();
break;
}
}
#include <boost/thread.hpp>
int main() {
boost::thread_group tg;
tg.create_thread([]{ listen(6767, "test.cpp"); });
tg.create_thread([]{
boost::this_thread::sleep_for(boost::chrono::seconds(1));
std::string response;
send_request("127.0.0.1", 6767, "TEST", response);
std::cout << "send_request returned " << response.size() << " bytes";
});
tg.join_all();
}
打印
Received the message: TEST
Size of result is 39845888
send_request returned 39845888 bytes
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 从 Boost ASIO 获取 epoll 描述符 io_service对象
- 如何在 Boost.Asio 中使用 Zero-copy sendmsg/receive
- C++ Boost::asio串行通信与Arduino无法写入
- 如何使用 Boost Asio 在 Android 上获取我的本地 udp IP 地址?
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 执行时使用 boost::asio::d eadline_timer 时出错
- Boost.Asio/OpenSSL HTTPS GET certificate trouble
- C++ boost::asio::ip::tcp::acceptor 有时不接受连接器?
- boost::asio data owning `ConstBufferSequence`
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 如何将boost::asio::d eadline_timer 与Qt一起使用?
- 将更高的优先级设置为 boost::asio 线程处理进程
- Async_read_until限制读取的字节大小(Boost::asio)
- Boost Asio - boost::bind 导致程序崩溃
- 使用Asio(Boost)通过网络发送灵活的数据量