boost下的asio异步高并发tcp服务器搭建

C++ 网络编程 asio 使用总结 - 知乎 (zhihu.com)

基于Boost::asio的多线程异步TCP服务器,实现了io_service线程池,测试了1万左右的并发访问,读写无压力_boost asio支持最大并发_E404的博客-CSDN博客

 单线程

 server.cpp

#include <cstdlib>
#include <ctime>

#include <iostream>
#include <memory>
#include <utility>
#include <string>

#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this <session>                   //从enable_shared_from_this继承的类需要使用智能指针管理资源
{
	public:
		session(tcp::socket socket) : socket_(std::move(socket)) { } 
		void start()
		{
			do_read();	
		}

	private:
		void do_read()
		{
			auto self(shared_from_this());                                      //对自己的引用计数+1
			socket_.async_read_some(boost::asio::buffer(data_,max_length),[this,self](boost::system::error_code ec , std::size_t length)
					{
						printf("recv data:%s\n",data_);
						if(!ec)
						{	
						do_write(length);
						}
					});
		}

		void do_write(std::size_t length)
		{
			auto self(shared_from_this());
			boost::asio::async_write(socket_,boost::asio::buffer(data_,length),[this,self](boost::system::error_code ec , std::size_t)
					{
						if(!ec)
						{
						do_read();		
						}
					});
		}



	private:
		tcp::socket socket_;
		enum {max_length = 1024};
		char data_[max_length];
};


class Server
{
	public:
		Server(boost::asio::io_service &io_service,short port) : acceptor_(io_service, tcp::endpoint(tcp::v4(),port)) , socket_(io_service)	{	}

		void start()
		{
			do_accept();
		}

	private:
		void do_accept()
		{
			acceptor_.async_accept(socket_ , [this](boost::system::error_code ec)    //创建一个socket连接
					{
					if(!ec)
					{
					auto newSession = std::make_shared<session>(std::move(socket_));
					newSession->start();
					}		
					do_accept();
					});
		}

		tcp::acceptor acceptor_;
		tcp::socket socket_;
};


int main(int argc,char *argv[])
{
	try
	{
		if(argc != 2)
		{
			std::cerr << "请输入端口号:" << std::endl;
			return 1;
		}
		boost::asio::io_service io_service;
		Server s(io_service,std::atoi(argv[1]));
		s.start();
		io_service.run();
	}catch(std::exception &e)
	{
		std::cerr << "异常:" << e.what() << std::endl;
	}
	return 0;
}

client.cpp

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <signal.h>
#include <arpa/inet.h>

#define MAXSIZE 1024
#define IP_ADDR "127.0.0.1"
#define IP_PORT 8888

int i_sockfd = -1;

void SigCatch(int sigNum)	//信号捕捉函数(捕获Ctrl+C)
{
	if(i_sockfd != -1)
	{
		close(i_sockfd);
	}
	printf("Bye~! Will Exit...\n");
	exit(0);
}

int main()
{
	struct sockaddr_in st_clnsock;
	char msg[1024];
	int nrecvSize = 0;

	signal(SIGINT, SigCatch);	//注册信号捕获函数

	if((i_sockfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)	//建立套接字
	{
		printf("socket Error: %s (errno: %d)\n", strerror(errno), errno);
		exit(0);
	}

	memset(&st_clnsock, 0, sizeof(st_clnsock));
	st_clnsock.sin_family = AF_INET;  //IPv4协议
	//IP地址转换(直接可以从物理字节序的点分十进制 转换成网络字节序)
	if(inet_pton(AF_INET, IP_ADDR, &st_clnsock.sin_addr) <= 0)
	{
		printf("inet_pton Error: %s (errno: %d)\n", strerror(errno), errno);
		exit(0);
	}
	st_clnsock.sin_port = htons(IP_PORT);	//端口转换(物理字节序到网络字节序)

	if(connect(i_sockfd, (struct sockaddr*)&st_clnsock, sizeof(st_clnsock)) < 0)	//主动向设置的IP和端口号的服务端发出连接
	{
		printf("connect Error: %s (errno: %d)\n", strerror(errno), errno);
		exit(0);
	}

	printf("======connect to server, sent data======\n");

	while(1)	//循环输入,向服务端发送数据并接受服务端返回的数据
	{
		fgets(msg, MAXSIZE, stdin);
		printf("will send: %s", msg);
		if(write(i_sockfd, msg, MAXSIZE) < 0)	//发送数据
		{
			printf("write Error: %s (errno: %d)\n", strerror(errno), errno);
			exit(0);
		}

		memset(msg, 0, sizeof(msg));
		if((nrecvSize = read(i_sockfd, msg, MAXSIZE)) < 0)	//接受数据
		{
			printf("read Error: %s (errno: %d)\n", strerror(errno), errno);
		}
		else if(nrecvSize == 0)
		{
			printf("Service Close!\n");
		}
		else
		{
			printf("Server return: %s\n", msg);
		}

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ljjjjjjjjjjj/article/details/132278900