サーバーアプリケーションを書いていますboost::asio
Server
ここでは、を所有するをインスタンス化します。io_service
- サーバーは、新しい接続を取得する前であっても
server.start()
、呼び出しServer::accept()
て新しいを作成するメソッドによって起動されますSession
- ハンドシェイクを行うメソッドを呼び出すコール
_acceptor.async_accept
バックを設定する呼び出しSession::handler()
。
新しいクライアントを取得する前にソケットを作成しても問題ありませんか? このコードでは、HTTP の場合は OK であるメッセージを書いた後にセッションが自動的に破棄され"Hello "
ますが、ステートフル通信を続けたいと考えています。そのため、ソケット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;
}