作为Boost.Asio的初学者,我很困惑io_service::run().如果有人能在这个方法阻止/解除阻止时向我解释,我将不胜感激.文件指出:
该
run()函数将阻塞,直到所有工作完成,并且不再需要调度处理程序,或者直到io_service停止处理.多个线程可以调用该
run()函数来设置一个线程池,io_service可以从中执行处理程序.在池中等待的所有线程都是等效的,并且io_service可以选择其中任何一个来调用处理程序.
run()函数的正常退出意味着io_service对象已停止(stopped()函数返回true).后续调用run(),run_one(),poll()或poll_one()将除非有预先调用立即返回reset().
以下陈述是什么意思?
[...]不再派遣处理人员[...]
在试图理解行为时io_service::run(),我遇到了这个例子(例3a).在其中,我观察到io_service->run()块和等待工单.
// WorkerThread invines io_service->run()
void WorkerThread(boost::shared_ptr<boost::asio::io_service> io_service);
void CalculateFib(size_t);
boost::shared_ptr<boost::asio::io_service> io_service(
new boost::asio::io_service);
boost::shared_ptr<boost::asio::io_service::work> work(
new boost::asio::io_service::work(*io_service));
// ...
boost::thread_group worker_threads;
for(int x = 0; x < 2; ++x)
{
worker_threads.create_thread(boost::bind(&WorkerThread, io_service));
}
io_service->post( boost::bind(CalculateFib, 3));
io_service->post( boost::bind(CalculateFib, 4));
io_service->post( …Run Code Online (Sandbox Code Playgroud) 我有一个小的ssl客户端,我已经在boost 1.55 asio编程,我想弄清楚为什么boost::asio::ssl::stream::async_shutdown()总是失败.客户端与boost文档中的ssl客户端示例非常相似(几乎完全相同),因为它通过boost::asio::ip::tcp::resolver::async_resolve()- > boost::asio::ssl::stream::async_connect()- > boost::asio::ssl::stream::async_handshake()回调序列.所有这些都按预期工作,async_handshake()回调变得非常明确boost::system::error_code.
从async_handshake()回调中,我调用async_shutdown()(我不传输任何数据 - 这个对象更多用于测试握手):
void ClientCertificateFinder::handle_handshake(const boost::system::error_code& e)
{
if ( !e )
{
m_socket.async_shutdown( boost::bind( &ClientCertificateFinder::handle_shutdown_after_success,
this,
boost::asio::placeholders::error ) );
}
else
{
m_handler( e, IssuerNameList() );
}
}
Run Code Online (Sandbox Code Playgroud)
handle_shutdown_after_success()然后调用,但始终有错误?错误是值= 2英寸asio.misc,即"文件结束".我用各种ssl服务器试过这个,我似乎总是得到这个asio.misc错误.这不是一个潜在的openssl错误告诉我,我可能会以某种方式滥用asio ......?
任何人都知道为什么会发生这种情况?我的印象是关闭连接async_shutdown()是正确的事情要做,但我想我可以打电话boost::asio::ssl::stream.lowestlayer().close()从openssl下关闭套接字,如果这是预期的方式这样做(事实上asio ssl示例似乎表明这是正确的关闭方式).
我正在研究一个多线程应用程序,其中一个线程充当从客户端接收命令的tcp服务器.该线程使用Boost套接字和acceptor等待客户端连接,从客户端接收命令,将命令传递给应用程序的其余部分,然后再次等待.这是代码:
void ServerThreadFunc()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_no));
for (;;)
{
// listen for command connection
tcp::socket socket(io_service);
acceptor.accept(socket);
// connected; receive command
boost::array<char,256> msg_buf;
socket.receive(boost::asio::buffer(msg_buf));
// do something with received bytes here
}
}
Run Code Online (Sandbox Code Playgroud)
这个线程大部分时间都在调用时被阻塞acceptor.accept().此时,线程仅在应用程序退出时终止.不幸的是,这会在main()返回后导致崩溃 - 我相信因为线程在单例被销毁后尝试访问应用程序的日志单例.(当我到这里时,就像那个,诚实的guv.)
当应用程序退出时,如何干净地关闭此线程?我已经读过可以通过从另一个线程关闭套接字来中断原始套接字上的阻塞accept()调用,但这似乎不适用于Boost套接字.我已经尝试使用Boost异步tcp echo服务器示例将服务器逻辑转换为异步i/o ,但这似乎只是为阻塞调用交换acceptor::accept()阻塞调用io_service::run(),所以我留下了同样的问题:一个阻塞打电话我不能打断.有任何想法吗?
我有一系列的C++结构,我试图用boost python包装.当这些结构包含数组时,我遇到了困难.我试图以最小的开销执行此操作,不幸的是我无法对结构本身进行任何修改.所以比如说我有
struct Foo
{
int vals[3];
};
Run Code Online (Sandbox Code Playgroud)
我希望能够在python中访问它,如下所示:
f = Foo()
f.vals[0] = 10
print f.vals[0]
Run Code Online (Sandbox Code Playgroud)
现在我正在使用一系列get/set函数,但这些函数非常不优雅且与访问其他非数组成员不一致.这是我目前的解决方案:
int getVals (Foo f, int index) { return f.vals[index]; }
void setVals (Foo& f, int index, int value) { f.vals[index] = value; }
boost::python::class_< Foo > ( "Foo", init<>() )
.def ( "getVals", &getVals )
.def ( "setVals", &setVals );
Run Code Online (Sandbox Code Playgroud)
我可以使用get/set函数(因为在某些情况下我需要实现自定义get或set操作)但是我不确定如何合并[]运算符来访问数组的元素.在其他可以使用[]运算符访问的类中,我已经能够使用_ getitem _和_ setitem _这些已经完美地运行了,但是我不知道如果可能的话我会如何对类成员执行此操作.
下面是SSL上下文初始化和验证回调注册的代码片段.如果我使用适当的证书连接SSL客户端,它将验证证书并按预期工作.
但是,如果我连接没有任何证书的客户端,那么它允许连接(实际上它不应该允许没有证书的连接).如果SSL客户端不发送证书,则它不会调用验证回调.
boost::asio::ssl::context_base::method SSL_version =
static_cast<boost::asio::ssl::context_base::method>(param_values[ID_PROTOCOL_VERSION].int32_value);
// load certificate files
boost::shared_ptr<boost::asio::ssl::context> context_ = boost::shared_ptr<boost::asio::ssl::context>(
new boost::asio::ssl::context(SSL_version)); // parasoft-suppress BD-RES-LEAKS "The memory is allocated via boost::shared_ptr, hence it'll be deallocated automatically"
p_ctx = boost::static_pointer_cast<void>(context_);
context_->set_options(boost::asio::ssl::context::default_workarounds);
context_->use_certificate_chain_file(cert_chain_file);
context_->use_certificate_file(cert_file, boost::asio::ssl::context::pem);
context_->use_private_key_file(cert_file, boost::asio::ssl::context::pem);
context_->set_verify_mode(boost::asio::ssl::verify_peer);
context_->set_verify_callback(boost::bind(&verify_certificate_cb, _1, _2));
Run Code Online (Sandbox Code Playgroud)
verify_certificate_cb 回调函数
bool verify_certificate_cb(bool preverified, boost::asio::ssl::verify_context& ctx)
{
std::cout << "Function : " << __func__ << " ----------------- Line : " << __LINE__ << std::endl;
int8_t subject_name[256];
X509_STORE_CTX *cts = ctx.native_handle();
int32_t length = 0;
X509* cert …Run Code Online (Sandbox Code Playgroud) 寻找一个boost :: asio(以及自己的提升)决定编写异步服务器.要存储传入的数据,我使用boost :: asio :: streambuf.我有一个问题.当我从客户端收到第二条消息后,我发现缓冲区中包含来自先前消息的数据.虽然我在输入缓冲区调用Consume方法.怎么了?
class tcp_connection
// Using shared_ptr and enable_shared_from_this
// because we want to keep the tcp_connection object alive
// as long as there is an operation that refers to it.
: public boost::enable_shared_from_this<tcp_connection>
{
...
boost::asio::streambuf receive_buffer;
boost::asio::io_service::strand strand;
}
...
void tcp_connection::receive()
{
// Read the response status line. The response_ streambuf will
// automatically grow to accommodate the entire line. The growth may be
// limited by passing a maximum size to …Run Code Online (Sandbox Code Playgroud) 我目前正在使用Boost.Python,并希望得到一些帮助来解决一个棘手的问题.
上下文
当C++方法/函数暴露给Python时,它需要释放GIL(全局解释器锁)以让其他线程使用解释器.这样,当python代码调用C++函数时,解释器可以被其他线程使用.现在,每个C++函数看起来像这样:
// module.cpp
int myfunction(std::string question)
{
ReleaseGIL unlockGIL;
return 42;
}
Run Code Online (Sandbox Code Playgroud)
为了传递它来提升python,我做:
// python_exposure.cpp
BOOST_PYTHON_MODULE(PythonModule)
{
def("myfunction", &myfunction);
}
Run Code Online (Sandbox Code Playgroud)
问题
这个方案工作正常,但它暗示这module.cpp取决于Boost.Python没有充分理由.理想情况下,只python_exposure.cpp应该依赖Boost.Python.
解?
我的想法是用Boost.Function这样包装函数调用:
// python_exposure.cpp
BOOST_PYTHON_MODULE(PythonModule)
{
def("myfunction", wrap(&myfunction));
}
Run Code Online (Sandbox Code Playgroud)
这里wrap将负责在通话期间解锁GIL myfunction.这种方法的问题是wrap需要具有相同的签名,myfunction这几乎意味着重新实现Boost.Function...
如果有人对此问题有任何建议,我将非常感激.
我正在尝试在项目中使用非Boost版本的Asio.我正在写一个回调stream_protocol::acceptor::async_accept.签名需要asio::placeholders::error通过但是当我这样做时,我收到以下错误:
error: no member named 'error' in namespace 'asio::placeholders'
在源代码之后,我可以看到错误,但是类型undefined,这对我来说是新的.我错过了什么吗?我应该对图书馆进行某种预处理吗?
Boost.Asio udp::endpoint有一个远程地址的成员.因为我正在监听多个接口(如下所示):
udp_socket(io_service, udp::endpoint(udp::v4(), port))
Run Code Online (Sandbox Code Playgroud)
在我的处理程序中,我不知道哪个网络接口收到了数据包.
如果没有遍历网络接口并在每个接口上寻找端点地址和我的IP之间的相似性,我可以从我收到消息的接口获取IP吗?
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
void print(boost::asio::deadline_timer* t, int* count)
{
if (*count < 5)
{
std::cout << *count << "\n";
++(*count);
t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
t->async_wait(boost::bind(print, t, count));
}
}
int main()
{
boost::asio::io_service io;
int count = 0;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
// t.async_wait(boost::bind(print, &t, &count));
t.async_wait([&]{ // compile error occurred
print(&t, &count);
});
io.run();
std::cout << "Final count is " << count << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
bind 和 lambda exp 之间有什么区别?我想语法没问题,问题是 async_wait 需要一个带有参数“const boost::system::error_code& e”的函数对象。