boost的库很稳定?不见得,官方测试例子被我弄崩溃了,,无奈中。。。。刚研究BOOST,看网上说的天花乱坠,说多少专
boost的库很稳定?不见得,官方测试例子被我弄崩溃了,,无奈中。。。。
刚研究BOOST,看网上说的天花乱坠,说多少专家编写的,性能非常稳定,我就下了一个BOOST 1.47的版本,找到了其中的ASIO的测试例子进行研究。
我首先要声明一点,,对于服务器和客户端进行数据传输的结构,不管客户端的逻辑怎么样,结构写的如何不对,只要是服务器因为客户端的操作而崩溃了,那么就是服务器本身的问题,因为不够强壮。
下面发一个BOOST 的测试例子,非常简单,源代码如下:
- C/C++ code
//// async_tcp_echo_server.cpp// ~~~~~~~~~~~~~~~~~~~~~~~~~//// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)///*async_accept()其实就是注册了一个回调函数;所以它会立即返回。 */#include <cstdlib>#include <iostream>#include <boost/bind.hpp>#include <boost/asio.hpp>using boost::asio::ip::tcp;class session{public: session(boost::asio::io_service& io_service) : socket_(io_service) { } tcp::socket& socket() { return socket_; } void start() { socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); }private: void handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { boost::asio::async_write(socket_, boost::asio::buffer(data_, bytes_transferred), boost::bind(&session::handle_write, this, boost::asio::placeholders::error)); } else { delete this; } } void handle_write(const boost::system::error_code& error) { if (!error) { socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { delete this; } } tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length];};class server{public: server(boost::asio::io_service& io_service, short port) : io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) { start_accept(); }private: void start_accept() { session* new_session = new session(io_service_); acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); } void handle_accept(session* new_session, const boost::system::error_code& error) { if (!error) { new_session->start(); } else { delete new_session; } start_accept(); } boost::asio::io_service& io_service_; tcp::acceptor acceptor_;};int main(int argc, char* argv[]){ try { if (argc != 2) { std::cerr << "Usage: async_tcp_echo_server <port>\n"; return 1; } boost::asio::io_service io_service; using namespace std; // For atoi. server s(io_service, atoi(argv[1])); io_service.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0;}这个服务器代码,可以在BOOST库里找到。
好了,下面看一下客户端的代码,也是基于代码库做的简单调整
- C/C++ code
//client.cpp#include <boost/asio.hpp>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>using boost::asio::ip::tcp;class client{public: client(boost::asio::io_service& io_service,tcp::endpoint& endpoint) : socket(io_service) { socket.async_connect(endpoint, boost::bind(&client::handle_connect,this,boost::asio::placeholders::error) ); memset(getBuffer, '\0',1024); } ~client() {}private: void handle_connect(const boost::system::error_code& error) { if(!error) { boost::asio::async_write(socket,boost::asio::buffer("hello,server!"), boost::bind(&client::handle_write,this,boost::asio::placeholders::error)); socket.async_read_some(boost::asio::buffer(getBuffer,1024), boost::bind(&client::handle_read,this,boost::asio::placeholders::error) ); } else { socket.close(); } } void handle_read(const boost::system::error_code& error) { if(!error) { std::cout << getBuffer << std::endl; socket.async_read_some( boost::asio::buffer(getBuffer,1024), boost::bind(&client::handle_read,this,boost::asio::placeholders::error) ); } else { socket.close(); } } void handle_write(const boost::system::error_code& error) { }private: tcp::socket socket; char getBuffer[1024];};int main(int argc,char* argv[]){ boost::asio::io_service io_service; tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"/*argv[1]*/),8100/*argv[2]*/); boost::shared_ptr<client> client_ptr(new client(io_service,endpoint));//【注意这行代码,是关键】 io_service.run(); return 0;}
好了,这是客户端的代码,客户端连接服务器,然后发送一段文字
以上的代码可以运行无误,一切正常。好了,我们来调整客户端的程序
boost::shared_ptr<client> client_ptr(new client(io_service,endpoint));
这行智能共享指针对象的创建,我们加个循环,改为如下:
for(int n=0; n < 10; n++)
boost::shared_ptr<client> client_ptr(new client(io_service,endpoint));
我们暂且不谈客户端这么写,是不是有问题,合乎不合乎逻辑,还是那句老话,如果服务器因为客户端的操作而崩溃了,那只能说明服务器不够稳定,这是服务器的问题,而不是客户端的问题,因为服务器要面对各种各样的数据和可能的攻击
程序运行,你会发现:测试例子崩溃了
我本来打算用这个BOOST的ASIO来实现一个服务器,可是目前这种情况,让我很无奈,崩溃的地方不是这个例子程序,而是库里的程序。
刚接触没几天,无奈的飘过
[解决办法]
网络库还是用专门的网络库吧
ace之类的。
[解决办法]
我表示不相信,所以特地验证了一下,结论与楼主可是刚好相反,试了4次,
第1次不加for,正常
第2次加for,客户端挂
第3次加for,客户端挂
第4次加for,客户端挂
代码是复制的楼主的。
注:本人已经将boost用于某项目生产环境。
[解决办法]
打补丁再测试. 否则没有说服力. 2005 2008不打补丁不能用的.
[解决办法]
boost 库毕竟还不是标准,有点Bug在所难免
[解决办法]
晕,哪是什么boost的bug,楼主最后改的那个for循环里,是用的share_ptr,出了大括号对象就析构了。等程序走到io_service.run()去异常回调时client对象早没了,不coredump才怪。要改成下面这样就没事。
for(int i = 0; i < 10; ++i)
{
client * client_ptr = new client(io_service,endpoint);//【注意这行代码,是关键】
}
io_service.run();
我在 boost 1.47.0 suse linux 10 sp3 gcc 4.1上试的
[解决办法]
楼主,无论如何,先把vc2003这个垃圾货升级掉再说。
[解决办法]
C++崩溃不是很正常吗。固有属性,和稳定性没关系。不过boost也是林子大了什么鸟都有。什么样的专家,代码写到那境界想稳定都难。
[解决办法]
表示看不懂
[解决办法]
[解决办法]
