virtual void handle_start() { tcp::resolver resolver(main_pool().io_service()); tcp::endpoint endpoint = *resolver.resolve(addr_query_); acceptor_.reset(new tcp::acceptor(main_pool().io_service())); acceptor_->open(endpoint.protocol()); acceptor_->set_option(tcp::acceptor::reuse_address(true)); acceptor_->bind(endpoint); acceptor_->listen(); start_accept(); std::cout << "Server started" << std::endl; }
/** accepts and keeps track of connections. reads data from connected peers and notifies through virtual methods if packets can be deserialized \param tls use GnuTLS for encryption \param port listen for incoming connections at this port \param maxPeers maximum number of connected peers */ void serve(bool tls, int port, int maxPeers) { if (tls) sock.reset(new TLSSocket()); else sock.reset(new Socket()); sock->setNonBlocking(); sock->bind(port); sock->listen(maxPeers); Select select; /* Wait for a peer, send data and term */ while (!closed) { select.reset(); if (peers.size() < maxPeers) select.input(sock->getFd()); for (typename Peers::iterator i = peers.begin(); i != peers.end(); i++) { select.input((*i)->getFd()); } if (select.select(100) == -1) continue; if (select.canRead(sock->getFd()) && peers.size() < maxPeers) { try { Socket* csock = sock->accept(); if (tls) { boost::threadpool::schedule(pool, boost::bind(&Server::handshake, this, csock)); } else { peers.push_back(boost::shared_ptr<PeerT>(new PeerT())); csock->setNonBlocking(); peers.back()->setup(csock); onJoin(*peers.back()); } } catch (SocketExcept& e) { std::cerr << e.what() << std::endl; } } if (tls) { Socket* sock = NULL; socketsReady.try_pop_front(sock); if (sock) { sock->setNonBlocking(); peers.push_back(boost::shared_ptr<PeerT>(new PeerT())); peers.back()->setup(sock); onJoin(*peers.back()); } } for (size_t i = 0; i < peers.size(); i++) { boost::shared_ptr<PeerT>& p = peers[i]; if (select.canRead(p->getFd())) p->onInput(); while (p->hasPacket()) { onPacket(*p); } } // collect dead peers size_t count = peers.size(); for (size_t i = 0; i < count; ) { if (!peers[i]->isActive()) { onLeave(*peers[i]); peers[i] = peers[peers.size() - 1]; count--; } else i++; } if (count < peers.size()) { peers.resize(count); } } }