我寫上boost::asio
升壓ASIO狀態服務器設計
- 在這裏,我實例化一個
Server
擁有一個io_service
- 服務器由
server.start()
方法,它調用Server::accept()
啓動服務器應用程序,並創建一個新的Session
甚至在它得到一個新的連接 - 呼叫
_acceptor.async_accept
這就是設置調用Session::handler()
方法能源部回調握手。
現在可以在獲得新客戶端之前創建套接字嗎? ,並且在這段代碼中,在編寫了一個"Hello "
消息後,會話被自動破壞,這在HTTP的情況下是好的,但是我想進行有狀態通信。所以套接字必須async_wait
才能讀取,只需寫出這個"Hallo "
即可。我也想知道這個設計是否可以?或者它有任何設計缺陷。
這裏去我的編譯代碼
〜
class Session: public boost::enable_shared_from_this<Session>, private boost::noncopyable{
private:
size_t _id;
boost::asio::ip::tcp::socket _socket;
public:
typedef boost::shared_ptr<Session> pointer;
static pointer create(boost::asio::io_service& ios){
return pointer(new Session(ios));
}
private:
explicit Session(boost::asio::io_service& ios): _socket(ios){
static size_t counter = 0;
_id = counter++;
std::cout << ">> Session " << id() << " constructing" << std::endl;
}
public:
void handler(const boost::system::error_code &ec){
const std::string message = (boost::format("HTTP/1.1 200 OK\r\nContent-Length: %2%\r\n\r\nHello, %1%!") % id() % (7+boost::lexical_cast<std::string>(id()).length())).str();
if(!ec){
boost::asio::async_write(_socket, boost::asio::buffer(message), boost::bind(&Session::write_handler, this));
}else{
std::cout << ec.message() << std::endl;
}
}
void write_handler(){
}
size_t id() const{
return _id;
}
boost::asio::ip::tcp::socket& socket(){
return _socket;
}
virtual ~Session(){
std::cout << ">> Session " << id() << " destructing" << std::endl;
}
};
class Server: public boost::enable_shared_from_this<Server>, private boost::noncopyable{
private:
boost::asio::io_service _ios;
boost::asio::ip::tcp::acceptor _acceptor;
public:
explicit Server(boost::asio::ip::tcp::endpoint& endpoint):_acceptor(_ios, endpoint){
}
void start(){
accept();
_ios.run();
}
void accept(){
std::cout << "accepting " << std::endl;;
Session::pointer session = Session::create(_ios);
_acceptor.async_accept(session->socket(), boost::bind(&Server::handler, this, session, boost::asio::placeholders::error));
}
void handler(Session::pointer session, const boost::system::error_code &ec){
if(!ec){
session->handler(ec);
}else{
//possible destroy session ? but how to destroy a shared pointer ?
}
accept();
}
};
int main(){
const unsigned int port = 5050;
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
Server server(endpoint);
server.start();
return 0;
}
謝謝。但是這個是無國籍的。它在一次寫入後破壞套接字。我想使它成爲有狀態的。怎麼樣 ? –
取決於你想要完成的事情。只要共享指針通過排隊處理程序保持活動狀態,那麼'Session'及其套接字就不會被銷燬。例如,您可以使用['async_read'](http://www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/reference/async_read/overload1.html)引入異步讀取循環。另外,請記住'HTTP'是一個無狀態協議;如果使用HTTP客戶端,可能會影響測試你的應用程序。 –
那麼我會用'telnet'或套接字來測試。正如你所說的,我在'boost :: bind(&Server :: handler,shared_from_this(),session,boost :: asio :: placeholders :: error)''中用'shared_from_this()'替換了'this'',這給了我運行時錯誤'接受 >>會話0正在構建 終止在拋出'boost :: exception_detail :: clone_impl>' 實例後調用'':tr1 :: bad_weak_ptr 已中止# –