⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpserver.cpp

📁 用c++编写http server的源码库,对socket等网络处理的代码可迅速转为己用.
💻 CPP
字号:
// -----------------------------------------------------------------// libpion: a C++ framework for building lightweight HTTP interfaces// -----------------------------------------------------------------// Copyright (C) 2007 Atomic Labs, Inc.  (http://www.atomiclabs.com)//// Distributed under the Boost Software License, Version 1.0.// See accompanying file COPYING or copy at http://www.boost.org/LICENSE_1_0.txt//#include <libpion/TCPServer.hpp>#include <libpion/PionEngine.hpp>#include <boost/bind.hpp>using boost::asio::ip::tcp;namespace pion {	// begin namespace pion// TCPServer member functionsTCPServer::TCPServer(const unsigned int tcp_port)	: m_logger(PION_GET_LOGGER("Pion.TCPServer")),	m_tcp_acceptor(PionEngine::getInstance().getIOService()),#ifdef PION_HAVE_SSL	m_ssl_context(PionEngine::getInstance().getIOService(), boost::asio::ssl::context::sslv23),#else	m_ssl_context(0),#endif	m_tcp_port(tcp_port), m_ssl_flag(false), m_is_listening(false){}void TCPServer::start(void){	// lock mutex for thread safety	boost::mutex::scoped_lock server_lock(m_mutex);	if (! m_is_listening) {		PION_LOG_INFO(m_logger, "Starting server on port " << getPort());				beforeStarting();		// configure the acceptor service		tcp::endpoint endpoint(tcp::v4(), m_tcp_port);		m_tcp_acceptor.open(endpoint.protocol());		// allow the acceptor to reuse the address (i.e. SO_REUSEADDR)		m_tcp_acceptor.set_option(tcp::acceptor::reuse_address(true));		m_tcp_acceptor.bind(endpoint);		m_tcp_acceptor.listen();		m_is_listening = true;		// unlock the mutex since listen() requires its own lock		server_lock.unlock();		listen();	}}void TCPServer::stop(void){	// lock mutex for thread safety	boost::mutex::scoped_lock server_lock(m_mutex);	if (m_is_listening) {		PION_LOG_INFO(m_logger, "Shutting down server on port " << getPort());			m_is_listening = false;		// this terminates any pending connections		m_tcp_acceptor.close();			// close all of the TCP connections managed by this server instance		std::for_each(m_conn_pool.begin(), m_conn_pool.end(),					  boost::bind(&TCPConnection::close, _1));		// clear the TCP connection management pool		m_conn_pool.clear();				afterStopping();	}}void TCPServer::listen(void){	// lock mutex for thread safety	boost::mutex::scoped_lock server_lock(m_mutex);		if (m_is_listening) {		// create a new TCP connection object		TCPConnectionPtr new_connection(TCPConnection::create(m_tcp_acceptor.io_service(),															  m_ssl_context, m_ssl_flag,															  boost::bind(&TCPServer::finishConnection,																		  this, _1)));		m_conn_pool.insert(new_connection);				// use the new object to accept a connection		if (m_ssl_flag) {#ifdef PION_HAVE_SSL			m_tcp_acceptor.async_accept(new_connection->getSSLSocket().lowest_layer(),										boost::bind(&TCPServer::handleAccept,													this, new_connection,													boost::asio::placeholders::error) );#else			PION_LOG_ERROR(m_logger, "SSL flag set for server, but support is not enabled");			new_connection->finish();#endif		} else {			m_tcp_acceptor.async_accept(new_connection->getSocket(),										boost::bind(&TCPServer::handleAccept,													this, new_connection,													boost::asio::placeholders::error) );		}	}}void TCPServer::handleAccept(TCPConnectionPtr& tcp_conn,							 const boost::system::error_code& accept_error){	if (accept_error) {		// an error occured while trying to a accept a new connection		// this happens when the server is being shut down		if (m_is_listening) {			tcp_conn->setKeepAlive(false);	// make sure it will get closed			finishConnection(tcp_conn);		}	} else {		// got a new TCP connection		PION_LOG_INFO(m_logger, "New" << (tcp_conn->getSSLFlag() ? " SSL " : " ")					  << "connection on port " << getPort());		// schedule the acceptance of another new connection		// (this returns immediately since it schedules it as an event)		if (m_is_listening) listen();				// handle the new connection		if (tcp_conn->getSSLFlag()) {#ifdef PION_HAVE_SSL			// SSL -> perform handshake first			tcp_conn->getSSLSocket().async_handshake(boost::asio::ssl::stream_base::server,													 boost::bind(&TCPServer::handleSSLHandshake,																 this, tcp_conn,																 boost::asio::placeholders::error) );#else			PION_LOG_ERROR(m_logger, "SSL flag set for server, but support is not enabled");			tcp_conn->setKeepAlive(false);	// make sure it will get closed			finishConnection(tcp_conn);#endif		} else {			// not SSL -> call the handler immediately			handleConnection(tcp_conn);		}	}}void TCPServer::handleSSLHandshake(TCPConnectionPtr& tcp_conn,								   const boost::system::error_code& handshake_error){	if (handshake_error) {		// an error occured while trying to establish the SSL connection		PION_LOG_WARN(m_logger, "SSL handshake failed on port " << getPort()					  << " (" << handshake_error.message() << ')');		tcp_conn->setKeepAlive(false);	// make sure it will get closed		finishConnection(tcp_conn);	} else {		// handle the new connection		PION_LOG_DEBUG(m_logger, "SSL handshake succeeded on port " << getPort());		handleConnection(tcp_conn);	}}void TCPServer::finishConnection(TCPConnectionPtr& tcp_conn){	if (tcp_conn->getKeepAlive()) {				// keep the connection alive		handleConnection(tcp_conn);	} else {		PION_LOG_INFO(m_logger, "Closing connection on port " << getPort());				// remove the connection from the server's management pool		boost::mutex::scoped_lock server_lock(m_mutex);		ConnectionPool::iterator conn_itr = m_conn_pool.find(tcp_conn);		if (conn_itr != m_conn_pool.end())			m_conn_pool.erase(conn_itr);		server_lock.unlock();	}}}	// end namespace pion

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -