c++ - 使我的函数调用 async_read 异步 Boost::asio
问题描述
我正在构建一个网络应用程序,作为 Boost asio 和整个网络的新手,我有这个疑问,这可能是微不足道的。我有这个应用程序,它从文件中读取并相应地调用 apis。我正在阅读 json (示例):
测试.json
{
"commands":
[
{
"type":"login",
"Username": 0,
"Password": "kk"
}
]
}
我的主程序如下所示:
int main() {
ba::io_service ios;
tcp::socket s(ios);
s.connect({{},8080});
IO io;
io.start_read(s);
io.interact(s);
ios.run();
}
void start_read(tcp::socket& socket) {
char buffer_[MAX_LEN];
socket.async_receive(boost::asio::null_buffers(),
[&](const boost::system::error_code& ec, std::size_t bytes_read) {
(void)bytes_read;
if (likely(!ec)) {
boost::system::error_code errc;
int br = 0;
do {
br = socket.receive(boost::asio::buffer(buffer_, MAX_LEN), 0, errc);
if (unlikely(errc)) {
if (unlikely(errc != boost::asio::error::would_block)) {
if (errc != boost::asio::error::eof)
std::cerr << "asio async_receive: error " << errc.value() << " ("
<< errc.message() << ")" << std::endl;
interpret_read(socket,nullptr, -1);
//close(as);
return;
}
break; // EAGAIN
}
if (unlikely(br <= 0)) {
std::cerr << "asio async_receive: error, read " << br << " bytes" << std::endl;
interpret_read(socket,nullptr, br);
//close(as);
return;
}
interpret_read(socket,buffer_, br);
} while (br == (int)MAX_LEN);
} else {
if (socket.is_open())
std::cerr << "asio async_receive: error " << ec.value() << " (" << ec.message() << ")"
<< std::endl;
interpret_read(socket,nullptr, -1);
//close(as);
return;
}
start_read(socket);
});
}
void interpret_read(tcp::socket& s,const char* buf, int len) {
if(len<0)
{
std::cout<<"some error occured in reading"<<"\n";
}
const MessageHeaderOutComp *obj = reinterpret_cast<const MessageHeaderOutComp *>(buf);
int tempId = obj->TemplateID;
//std::cout<<tempId<<"\n";
switch(tempId)
{
case 10019: //login
{
//const UserLoginResponse *obj = reinterpret_cast<const UserLoginResponse *>(buf);
std::cout<<"*********[SERVER]: LOGIN ACKNOWLEDGEMENT RECEIVED************* "<<"\n";
break;
}
}
std::cout << "RX: " << len << " bytes\n";
if(this->input_type==2)
interact(s);
}
void interact(tcp::socket& s)
{
if(this->input_type == -1){
std::cout<<"what type of input you want ? option 1 : test.json / option 2 : manually through command line :";
int temp;
std::cin>>temp;
this->input_type = temp;
}
if(this->input_type==1)
{
//std::cout<<"reading from file\n";
std::ifstream input_file("test.json");
Json::Reader reader;
Json::Value input;
reader.parse(input_file, input);
for(auto i: input["commands"])
{
std::string str = i["type"].asString();
if(str=="login")
this->login_request(s,i);
}
std::cout<<"File read completely!! \n Do you want to continue or exit?: ";
}
}
发送工作正常,消息被发送并且服务器以正确的方式响应,但我需要理解的是为什么控件不去on_send_completed(打印发送的 x 字节)。它也不会打印消息[SERVER]: LOGIN ACKNOWLEDGMENT RECEIVED,我知道我缺少一些基本的东西或做错了什么,请纠正我。
login_request 函数:
void login_request(tcp::socket& socket,Json::Value o) {
/*Some buffer being filled*/
async_write(socket, boost::asio::buffer(&info, sizeof(info)), on_send_completed);
}
提前致谢!!
解决方案
从粗略的扫描来看,您似乎重新定义buffer_
了已经是一个类成员(IO
大概是)。
它被本地 in 隐藏start_read
,它既是 UB(因为生命周期在异步读取操作完成之前结束),也使得它_buffer
不使用成员。
我看到很多令人困惑的代码。为什么要从完成处理程序中进行同步读取?
我认为您可能正在寻找组合操作读取(boost::asio::async_read 和 boost::asio::async_until)
推荐阅读
- r - 计算列表中名称的功能?
- python - Pandas python如何将嵌套的JSON对象转换为行和列
- ffmpeg - 使用 FFmpeg 将图像转换为具有可变 fps 的视频
- blazor - Blazor:如何将价值从一个组件发送到另一个组件?
- ruby-on-rails - 使用 RubyMine 进行 Rails 远程调试
- spring - 春季云AWS sendAndReceive
- java - 坚持石英作业结果
- ios - SwiftUI 本地化不适用于 @State 字符串
- python - 我如何将 pitch_bend 更改添加到函数piano_roll_to_pretty_midi 以制作音乐?
- angular - 使用 Angular 9 从后端获取数据数组