- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想检查 Boost Asio
是否真的执行异步连接。根据the diagrams corresponding to the asynchronous calls发表在Asio
的基础知识中,当io_service
向操作系统发出信号时,操作开始,因此我理解在执行async.connect
指令系统尝试执行该连接。
我的理解是,如果您不调用 run
,您只会错过结果,但操作可能已完成。因此,我尝试使用 nc -l -p 9000
创建一个虚拟服务器,然后使用下面附带的代码。
使用调试器,我一个语句一个语句地执行,并在 run
调用 io_service
之前停止。在服务器中,什么也没有发生。与连接无关——这很明显,因为虚拟服务器不会告诉你——也没有关于 async_write
的信息。
调用 run
函数后,服务器端会立即弹出相应的消息。我一直在 Boost
的 IRC channel 上询问,在展示了我的 strace
之后,一个非常聪明的人告诉我,这可能是因为套接字直到 才准备好run
被调用。显然,这不会发生在 Windows 上。
这是否意味着在 GNU/Linux 操作系统下异步并不是真正的异步?这是否意味着网站中显示的图表不符合 GNU/Linux 环境?
关于“不是真正的异步”的注意事项:是的,它不会阻塞调用,因此线程会继续运行并做一些事情,但我的意思是异步开始执行后立即执行操作。
非常感谢您。
代码
#include <iostream>
#include <string.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
void connect_handler(const boost::system::error_code& error)
{
if(error)
{
std::cout << error.message() << std::endl;
exit(EXIT_FAILURE);
}
else
{
std::cout << "Successfully connected!" << std::endl;
}
}
void write_handler(const boost::system::error_code& error)
{
if(error)
{
std::cout << error.message() << std::endl;
exit(EXIT_FAILURE);
}
else
{
std::cout << "Yes, we wrote!" << std::endl;
}
}
int main()
{
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket socket(io_service);
boost::asio::ip::tcp::endpoint endpoint(
boost::asio::ip::address::from_string("127.0.0.1"), 9000);
socket.async_connect(endpoint, connect_handler);
std::string hello_world("Hello World!");
boost::asio::async_write(socket, boost::asio::buffer(hello_world.c_str(),
hello_world.size()), boost::bind(write_handler,
boost::asio::placeholders::error));
io_service.run();
exit(EXIT_SUCCESS);
}
我的跟踪
futex(0x7f44cd0ca03c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x7f44cd0ca048, FUTEX_WAKE_PRIVATE, 2147483647) = 0
eventfd2(0, O_NONBLOCK|O_CLOEXEC) = 3
epoll_create1(EPOLL_CLOEXEC) = 4
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC) = 5
epoll_ctl(4, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLERR|EPOLLET, {u32=37842600, u64=37842600}}) = 0
write(3, "\1\0\0\0\0\0\0\0", 8) = 8
epoll_ctl(4, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLERR, {u32=37842612, u64=37842612}}) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 6
epoll_ctl(4, EPOLL_CTL_ADD, 6, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET, {u32=37842704, u64=37842704}}) = 0
ioctl(6, FIONBIO, [1]) = 0
connect(6, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
epoll_ctl(4, EPOLL_CTL_MOD, 6, {EPOLLIN|EPOLLPRI|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLET, {u32=37842704, u64=37842704}}) = 0
epoll_wait(4, {{EPOLLIN, {u32=37842600, u64=37842600}}, {EPOLLOUT, {u32=37842704, u64=37842704}}}, 128, -1) = 2
poll([{fd=6, events=POLLOUT}], 1, 0) = 1 ([{fd=6, revents=POLLOUT}])
getsockopt(6, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
sendmsg(6, {msg_name(0)=NULL, msg_iov(1)=[{"Hello World!", 12}], msg_controllen=0, msg_flags=0}, MSG_NOSIGNAL) = 12
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 5), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f44cd933000
write(1, "Successfully connected!\n", 24Successfully connected!
) = 24
epoll_wait(4, {}, 128, 0) = 0
write(1, "Yes, we wrote!\n", 15Yes, we wrote!
) = 15
exit_group(0) = ?
+++ exited with 0 +++
最佳答案
关于 boost.asio 的一个奇怪的事情——不是它独有的,但通常不同于特定于操作系统的异步网络框架——是它不依赖于辅助线程。这有许多重要的后果,可以归结为:boost.asio 不适合在后台做事。相反,它用于在前台做多项事情。
io_service::run()
是 boost.asio 的“枢纽”,使用 boost.asio 的单线程程序应该预计大部分时间都在 io_service 中等待::run()
,或执行它调用的完成处理程序。根据特定于操作系统的内部实现,在调用该函数之前可能会或可能不会运行特定的异步操作,这就是为什么调用它基本上是您启动初始异步请求后要做的第一件事.
将 async_connect
视为使用异步操作“武装”您的 io_service。实际的异步发生在 io_service::run()
期间。事实上,调用 async_connect
后立即调用 async_write
是一件很奇怪的事情,我对它的工作原理感到有点惊讶。通常,您会从 connect_handler
中执行(或者更确切地说,“arm”)async_write
,因为只有在那个时候您才有连接的套接字。
关于c++ - async_connect 在 GNU/Linux 下真的是异步的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37731322/
我正在尝试检查 boost::asio::async_connect 是否成功,但我没有收到错误,即使服务器未启动。如何正确检查是否成功?谢谢! main.cpp #include #include
我正在尝试为我的项目从 boost TCP 客户端示例创建一个客户端类,并且我注意到有时在连接到不存在的主机时不会调用 handle_connect。 我在堆栈上读过类似的问题,人们忘记运行 io_s
短篇小说:socket.async_connect(...) 之后的调用 socket.cancel() 完美运行,即调用了完成处理程序;但是对于 asio::async_connect(socket
我想知道传递给上述方法的对象的生命周期是多少。 异步解析 ip::basic_resolver::async_resolve(const query & q, ResolveHandler handl
我在修改 asio 的阻塞套接字时没有遇到任何问题,但我对异步套接字的深入研究一直是一场噩梦。也许我只是累坏了: using boost::asio::ip::tcp; boost::asio
我偶尔会遇到这个问题。我们有一个使用 boost::asio 和 deadline_timer 实现的 http 客户端来处理连接/请求超时。 async_connect 被调用。 deadline_
我正在编写一个使用 boost asio 连接到远程套接字的小型客户端类。如果初始连接失败,它应该能够尝试重新连接。 在测试该场景时,即没有打开的远程套接字,第一次正确调用了 async_connec
我正在使用 asio 构建一个可以通过 TCP 或 unix 套接字连接到远程系统的网络库。我使用 asio::generic::stream_protocol::socket,它同时具有 conne
我正在尝试实现带有超时的 async_connect()。 async_connect_with_timeout(socket_type & s, std::function
我想检查 Boost Asio 是否真的执行异步连接。根据the diagrams corresponding to the asynchronous calls发表在Asio的基础知识中,当io_s
我有一个服务器应用程序,其中我只接受一个带有 boost::asio::ip::tcp::acceptor 和 async_accept 的客户端。 我运行客户端应用程序并使用 boost::asio
我已经关注了 documentation and examples由 boost asio 实现提供,但在将我的客户端连接到服务器后没有任何运气。无论成功还是失败,处理程序都不会被调用。我已验证服务器
我正在学习使用 Boost ASIO。这是我的代码改编自 Boost 文档的 chat example . class AsioCommunicationService { AsioCommunica
我成功地实现了 async_connect,使用它作为一个自由函数和一个 lambda 作为 connect_handler,如下所示: auto self(shared_from_this());
我刚刚通过 TCPView 发现使用 boost::asio 建立的一个 TCP 连接创建了两个连接。其中之一使用本地端口,第二个使用所需的远程端口。为什么?这种行为正常吗?有没有办法只创建一个? 这
我正在尝试运行以下代码: some_sock.async_connect(...); // handle_connect() sets the 'condition' flag boost::asio
我是一名优秀的程序员,十分优秀!