2016-10-19 1 views
1

부스트 대신 C++ 11을 사용하여 Daytime Async TCP Server example을 기반으로하는 비동기 서버를 만들었습니다.asio async 서버에서 연결을 허용하지 않습니다.

class TcpServer { 
    public: 
    static std::shared_ptr<TcpServer> make(int port); 
    ~TcpServer(); 
    void start(); 
    protected: 
     TcpServer(int port); 
     void init(int port); 
     void createSession(); 
     void onConnect(std::vector<std::shared_ptr<TcpSession>>::iterator session_iter, const asio::error_code& error); 
     asio::io_service mService; 
     std::thread mServiceThread; 
     asio::ip::tcp::acceptor mAcceptor; 
     asio::ip::tcp::socket mSocket; 
     asio::ip::tcp::endpoint mLocalEndpoint; 
     std::vector < std::shared_ptr<TcpSession>> mSessions; 
    }; 

std::shared_ptr<TcpServer> TcpServer::make(int port) { 
    std::shared_ptr<TcpServer> Server(new TcpServer(port)); 
    return Server; 
} 

TcpServer::TcpServer(int port) : mSocket(mService), mAcceptor(mService) { 
    init(port); 
} 

TcpServer::~TcpServer() { 
    mSocket.cancel(); 
    mService.stop(); 
    if (mServiceThread.joinable()) { 
     mServiceThread.join(); 
    } 
} 

void TcpServer::start() { 
    createSession(); 
} 

void TcpServer::init(int port) { 
    mLocalEndpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port); 

    std::printf("TcpServer -- Creating endpoint %s:%d ...\n", mLocalEndpoint.address().to_string().c_str(), mLocalEndpoint.port()); 

    mAcceptor.open(mLocalEndpoint.protocol()); 
    mAcceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); 
    mAcceptor.bind(mLocalEndpoint); 
    mAcceptor.listen(); 

    mServiceThread = std::thread([&] { 
     mService.run(); 
    }); 

} 

void TcpServer::createSession() { 
    std::printf("TcpServer -- Creating new session...\n"); 
    std::shared_ptr<TcpSession> newSession = TcpSession::make(mService); 
    std::vector<std::shared_ptr<TcpSession>>::iterator iterator = mSessions.insert(mSessions.end(), newSession); 

    mAcceptor.async_accept(newSession->getSocket(), 
     [this, iterator](const asio::error_code &error) { 
     std::printf("Async Accept\n"); 
     onConnect(iterator, error); 
    }); 
} 

void TcpServer::onConnect(std::vector<std::shared_ptr<TcpSession>>::iterator session_iter, const asio::error_code& error) { 
    if (!error) { 
     std::printf("TcpServer -- Connection from %s received!\n", (*session_iter)->getSocket().remote_endpoint().address().to_string().c_str()); 

    // Write a response 
    //auto buff = std::make_shared<std::string>("Hello World!\r\n\r\n"); 

    //asio::async_write((*session_iter)->getSocket(), asio::buffer(*buff), 
    // [this, session_iter](const asio::error_code &error, std::size_t bytesReceived) { 
    // onWrite(session_iter, error, bytesReceived); 
    //}); 

    // begin listening 
    //receive(session_iter); 

} 
else { 
    std::printf("TcpServer::onConnect -- Error receiving data. %s\n", error.message().c_str()); 
    mSessions.erase(session_iter); 
} 
} 

다음 작은 TcpSession 클래스 :

class TcpSession { 
    public: 
     ~TcpSession(); 
     static std::shared_ptr<TcpSession> make(asio::io_service& service){ 
     asio::ip::tcp::socket& getSocket() { 
      return mSocket; 
     } 
    protected: 
     TcpSession(asio::io_service& service); 
     asio::ip::tcp::socket mSocket; 
    }; 

I create an instance of the server and run it like so: 

void main() { 
    mServer = TcpServer::make(8060); 
    mServer->start(); 
} 

I then try to connect to it with a lightweight TCP/IP app like TCP/IP Builder (for Windows); however, I never see any of the messages from `onConnect` suggesting that I've made a connection. 

사람이 잘못 될 일의 어떤 제안이 있습니까 여기에 서버 클래스입니까?

감사합니다.

답변

2

문제점 : asio :: io_service :: run()은 작업 부족으로 즉시 반환됩니다. io_service를 계속 실행하려면 io_service::work 개체를 만들어야합니다.

+0

그게 다야! 감사! –

1

방화벽이 프로세스/포트를 차단할 가능성이 있습니까?

+0

나는 그것을 고려했다. Windows 방화벽이 비활성화되었으므로 문제가되지 않아야합니다. 나는 또한 asio UDP 수신기를 시도하고 잘 소켓 메시지를 보낼 수있었습니다. –

관련 문제