在同一系统上运行的多个boost::asio-ssl客户端
multiple boost::asio ssl clients running on same system
我有一个简单的Boost ASIO SSL客户端,它调用web api。客户端是对Boost SSL文档示例的轻微修改。
//http.h
class Http {
public:
static void WebApiCall(...);
}
//http.cpp
void Http::WebApiCall(...) {
try {
// .......
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(serverip, serverport);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::tlsv1); // ERROR # 1
// ....
// Setting SSL Context Properties Here
// ....
boost::shared_ptr<boost::asio::ssl::stream<tcp::socket> > ssocket(new boost::asio::ssl::stream<tcp::socket>(io_service, ctx));
boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
ssocket->lowest_layer().connect(endpoint);
boost::system::error_code er;
ssocket->handshake(boost::asio::ssl::stream_base::client,er);
boost::asio::streambuf request;
std::ostream request_stream(&request);
// ....
// Set Headers & Body of HTTP Request here
// ....
size_t written = 0;
written = boost::asio::write(*ssocket, request); // ERROR # 2
// .....
// Read server response
boost::asio::streambuf response;
boost::system::error_code error;
int read_bytes = 0;
std::string TempBuf = "";
std::ostringstream responseStringstream;
std::stringstream response_stream;
while ( boost::asio::read(*ssocket,response,boost::asio::transfer_at_least(1), error)) {
read_bytes = read_bytes + response.size();
responseStringstream << &response;
}
}
// Do some stuff with server response....
// ....
} catch ( const boost::system::system_error &error ) {
// Print the exception ..
}
}
// client.cpp
Http::WebApiCall(<api_to_call>)
您可以看到它是一个简单的HTTP客户端,带有一个静态函数,它使用ASIO实现了实际的启用SSL的HTTP客户端。
用例:
1000个进程正在一台机器上运行此客户端。所有进程都在大致相同的时间内周期性地(例如每一分钟)向一个资源发出POST请求。机器是Ubuntu,我似乎没有内存不足(我有大约6GB的空闲空间)
这个客户端运行得很好,但在一种情况下,我必须模拟服务器上的一些负载,我已经启动了这个客户端的1000个进程,所有进程都在一台计算机上,所有进程使用相同的公共证书向同一服务器调用相同的API,只是每个客户端都有自己的OAuth令牌。在这种情况下,我得到了两种类型的异常:
错误:
错误#2:写入时某些客户端(不是全部)出现错误(写入:短读)。从不同的论坛和Boost来源来看,服务器似乎正在发送SSL_Shutdown,导致ASIO抛出此错误,根据我的发现,这是正常行为。我的问题是,为什么服务器此时发送SSL_Shutdown?这与多个进程从同一台机器调用同一资源有关吗?从ASIO文档来看,ASIO SSL不是线程安全的,但在这种情况下,我只运行一个线程,但运行不同的进程(我认为这是完全安全的),此外,上面的代码本身就是线程安全的。底层openssl的行为是否不稳定?
错误#1:有时在创建Boost ASIO SSL上下文时会出现异常,只是简单地说"Context:SSL ERROR"。同样的想法,为什么它会这样?这与多个进程有关吗?openssl在这种情况下是不是把事情搞混了?
在过去的一年里,我的客户每台机器只运行一个进程,我以前从未见过这些错误。任何想法都值得赞赏。
cco(只是提到了OAuth,但我不认为这与它有任何关系)
-
Q:一些客户端(并非全部)在写入时出错(写入:短读)。从不同的论坛和Boost来源来看,服务器似乎正在发送SSL_Shutdown,导致ASIO抛出此错误,根据我的发现,这是正常行为。
最有可能的原因是您正在将系统推到资源限制之外。例如,客户端或服务器可能会用完文件句柄。例如,在我的Linux盒子上,打开的文件数量默认限制为
1024
:ulimit -a
输出:core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 256878 max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 95 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 256878 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
-
Q:我的问题是,为什么服务器此时发送SSL_Shutdown?
很可能是因为以上原因。
-
Q:这与多个进程从同一台机器调用同一资源有关吗?
没有。
-
Q:从ASIO文档来看,ASIO SSL不是线程安全的,但在这种情况下,我只运行一个线程,但运行不同的进程(我认为这是完全安全的),此外,上述代码本身也是线程安全的。底层openssl的行为是否不稳定?
线程安全或底层SSL库不是这里的问题。
-
Q:有时在创建Boost ASIO SSL上下文时会出现异常,只是简单地说"Context:SSL error"。同样的想法,为什么它会这样?这与多个进程有关吗?openssl在这种情况下是不是把事情搞混了?
不太可能,但
ssl::context
的每个实例都会产生开销,这是可能的。您可以尝试静态地/在循环之外分配它。也就是说,如果SSL上下文只是遇到(相同的)资源限制,初始化更有可能,因为它可能会打开一些系统配置文件和/或检查是否存在已知路径(例如CApath等)
- C++ 关闭Boost ASIO SSL套接字的最佳方法是什么?
- 使用 Boost ASIO 和 SSL 时出现"Wrong Version Number"错误 (C++)
- 从或写入boost :: asio :: ssl :: stream :: next_layer()旁路SSL解密/加密
- 使用 boost::asio SSL 服务器减少每个连接的内存使用量
- boost::asio::ssl::context::context(boost::asic::ssl::context
- 在同一系统上运行的多个boost::asio-ssl客户端
- boost::asio-ssl链接错误
- Boost ASIO:SSL握手()永远不会结束
- 可以在多个ssl流之间共享boost::asio::ssl::上下文
- Boost asio & ssl & error code
- boost asio SSL async_shutdown总是以错误结束
- 如何修改boost::asio::ssl::context的方法
- 如何使用boost::asio SSL验证客户端证书
- Boost asio SSL简单加密程序
- Boost Asio SSL流中lowest_layer()和next_layer()的区别
- boost::asio::ssl::context::add_verify_path
- 什么是boost::asio::ssl::context::load_verify_file以及如何使用它
- Boost Asio SSL握手永远不会返回
- boost asio-ssl async_write给我发了很多胡言乱语
- Boost asio SSL -连接成功后尝试发送请求