分享几个常见的开源服务器框架以及boost::asio的一个demo

一、常见的开源网络库:

  • Adaptive Communication Environment,简称ACE,自适应通信环境。ACE代码复杂,封装繁琐,框架比较笨重,难修改,默认使用select,并非epoll;
  • ZeroMQ,简称ZMQ。轻量级,简洁且灵活;
  • boost::asio,本文将实现一个使用asio的demo;
  • libevent:基于epoll的异步处理机制的库,多数被用来进行网络编程;
  • tinyserver:微型服务器,默认是单线程允许,所以实际的生成价值并不高;
  • LibSourcey:是一个基于c++14标准,用于高性能网络服务器开发的,较冷门,参考资料少;
  • Casablanca:基于C++11标准,C++ REST SDK的别名,微软开源的项目,基于REST API协议,集成了 boost::asio;
  • websocket++:基于 boost库的一个封装,封装了asio。

上面的一些库并没有接触过,先在这里做个标记,以后有时间了慢慢的啃,接下来给出一个使用boost::asio进行网络通信的demo。

二、boost::asio简介:

在这里先简单的介绍一下这个库,在1.4.3版本引入epoll来实现异步处理,可以结合其他boost库来实现更为轻大的功能,十分的灵活,充分理解架构后,我们可以在其基础上进行自定义。

  • 几个重要的类:
boost::asio::ip::tcp::socket(async_connect,async_accept)
boost::asio::io_service   //封装IO操作
boost::asio::ip::tcp::acceptor
  • code:
#include <iostream>
#include <string>
#include <unordered_map>
#include <csignal>
#include "server.h"
#include "log.h"
#include <boost/asio.hpp> 
#include <boost/bind.hpp>

void accept_handler(const boost::system::error_code& _ec);


boost::asio::io_service ios;
unsigned short port;
boost::asio::ip::tcp::acceptor* pacceptor;

boost::asio::ip::tcp::socket _socket(ios);
std::string netbuffer;


void write_handler(const boost::system::error_code &ec, std::size_t bytes_transferred) {
	_socket.close();
	log("[Info]", "server complete");
	pacceptor->async_accept(_socket, accept_handler);
}

void read_handler(const boost::system::error_code &ec, std::size_t bytes_transferred) {
	log("[Info]", "recv:" + netbuffer);
	std::string http_data = "HTTP/1.1 200 OK\r\nServer: loong\r\nContent-type: text/html\r\n\r\n" + netbuffer;
	log("[Info]", http_data);
	_socket.async_write_some(boost::asio::buffer(http_data), write_handler);
}


void accept_handler(const boost::system::error_code& _ec) {
	if (_ec) {
		log("[Error]", "server accept");
		return;
	}

	log("[Info]", _socket.remote_endpoint().address().to_string());
	_socket.async_read_some(boost::asio::buffer(netbuffer), read_handler);
}



void handler(int s) {
	log("[Info]", "Server exit!");
	if (pacceptor != NULL) {
		boost::asio::ip::tcp::acceptor* tmp = pacceptor;
		pacceptor = NULL;
		delete tmp;
	}
	exit(0);
}

int main(int argc, char **argv) {
	netbuffer.resize(4096);
	if (argc != 3 || argv[1][0] != '-' || argv[1][1] != 'p') {
		std::cout << "[Usage] " << argv[0] << " -p <port>" << std::endl;
		return 0;
	}
	port = (unsigned short)strtol(argv[2], nullptr, 10);
	daemonize();
	signal(SIGINT, handler);
	pid_t server_pid;
	while ((server_pid = server_singleton()) != -1) {
		kill(server_pid, SIGINT);
	}
	log("[Info]", "Server start!");
	pacceptor = new boost::asio::ip::tcp::acceptor(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port));
	pacceptor->async_accept(_socket, accept_handler);
	log("[Info]", "server start 1.");
	ios.run();
	log("[Info]", "server start 2.");
	boost::asio::ip::tcp::acceptor* tmp = pacceptor;
	pacceptor = NULL;
	delete tmp;
	return 0;
}
  • log.h:
#ifndef LOONG_LOG_H
#define LOONG_LOG_H

#include <string>
#include <cstring>

#define HANDLE(X) \
    do { \
        if ((X) == -1) { \
            log("[Error]", strerror(errno)); \
            exit(1); \
        } \
    } while(0)

void log(const std::string &log_head, const std::string &log_body);


#endif //LOONG_LOG_H
  • server.h
#ifndef LOONG_SERVER_H
#define LOONG_SERVER_H

#include <unistd.h>

void daemonize();
pid_t server_singleton();


#endif //LOONG_SERVER_H

剩下的以后有机会深入学习一下,最近看到公司的一些项目在用websocket,之前被公司的大佬实现了一些,需要我搞一点其他的东西,我想说,看别人的代码是真的不舒服…

就先这样吧,以后周末有时间了完善一下,深入一下。

发布了237 篇原创文章 · 获赞 98 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/KingOfMyHeart/article/details/100024350