asio的网络基本模板(单例模式 消息队列 )

 // MyAsio.cpp: 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include <assert.h>
#include "NetMgr.h" using namespace DEF;
/*
write by def
技术博客 http://www.cnblogs.com/itdef/
技术交流群 群号码:432336863
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
部分老代码存放地点
http://www.oschina.net/code/list_by_user?id=614253
*/ int main()
{
NetMgr& p = NetMgr::Instance();
NetMgr& p1 =NetMgr::Instance();
assert(&p == &p1);
//std::cout << &p << " " << &p1;
p.Start();
return ;
}

MyAsio.cpp

 #pragma once
#include "Pre.h"
#include <iostream>
#include <atomic> #include <boost/asio.hpp>
#include <boost/bind.hpp> #include "SyncQueue.h" /*
write by def
技术博客 http://www.cnblogs.com/itdef/
技术交流群 群号码:432336863
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
部分老代码存放地点
http://www.oschina.net/code/list_by_user?id=614253
*/ NAMESPACEBEGIN(DEF)
using boost::asio::ip::tcp; const char MAGIC_CHAR = '|'; #pragma pack (push,1)
struct BufferHead {
char flag; // should equal '|'
unsigned int bufferLenth;
BufferHead() {
flag = ;
bufferLenth = ;
}
BufferHead(char f, unsigned int len) {
flag = f;
bufferLenth = len;
}
}; struct BufferStruct {
enum {
BUF_MAX_LENTH = *
};
BufferHead head;
char bufBody[BUF_MAX_LENTH];
BufferStruct() {}
BufferStruct(const BufferStruct& b) {
head = b.head;
memcpy(bufBody, b.bufBody, b.head.bufferLenth);
}
char* GetBody() { return bufBody; }
unsigned int GetLength() { return head.bufferLenth; }
};
#pragma pack(pop) class tcp_connection
: public std::enable_shared_from_this<tcp_connection>
{
public:
typedef std::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_service& io_service, std::shared_ptr<SyncQueue<std::string>> p_messageQueue)
{
return pointer(new tcp_connection(io_service, p_messageQueue));
}
boost::asio::ip::tcp::socket& socket()
{
return socket_;
}
void start();
~tcp_connection() {
std::cout << std::endl << "Delete tcp_connection=" << --i << std::endl;
}
private:
tcp_connection(boost::asio::io_service& io_service, std::shared_ptr<SyncQueue<std::string>> p_messageQueue)
: socket_(io_service), p_messageQueue_(p_messageQueue)
{
std::cout << "New tcp_connection " << ++i << " times" << std::endl;
}
void handle_read_head(const boost::system::error_code& error,size_t bytes_transferred);
void handle_read_body(const boost::system::error_code& error,size_t bytes_transferred);
boost::asio::ip::tcp::socket socket_;
std::shared_ptr<SyncQueue<std::string>> p_messageQueue_;
static std::atomic_int i;
BufferStruct recvBuff_;
}; class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service, int port, std::shared_ptr<SyncQueue<std::string>> p_queue);
private:
void start_accept() {
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service(), p_messageQueue_);
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
} start_accept();
}
std::shared_ptr<SyncQueue<std::string>> p_messageQueue_;
boost::asio::io_service& io_service_;
boost::asio::ip::tcp::acceptor acceptor_;
}; NAMESPACEEND(DEF)

netasio.h

 #include "NetAsio.h"

 using namespace DEF;
/*
write by def
技术博客 http://www.cnblogs.com/itdef/
技术交流群 群号码:432336863
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
部分老代码存放地点
http://www.oschina.net/code/list_by_user?id=614253
*/
std::atomic_int tcp_connection::i = ;
tcp_server::tcp_server(boost::asio::io_service& io_service, int port, std::shared_ptr<SyncQueue<std::string>> p_queue):
io_service_(io_service),
acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
p_messageQueue_(p_queue)
{
start_accept();
} void tcp_connection::start() {
boost::asio::async_read(socket_, boost::asio::buffer(&recvBuff_.head,sizeof(recvBuff_.head)),
boost::bind(&tcp_connection::handle_read_head, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
} //接受包头内容
void DEF::tcp_connection::handle_read_head(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (error == boost::asio::error::eof) {
return;
}else if (error) {
std::cerr << " socket recv head error!! " << error.message() << std::endl;
return;
}
char *pBuf = recvBuff_.GetBody();
boost::asio::async_read(socket_, boost::asio::buffer(pBuf, recvBuff_.head.bufferLenth),
boost::bind(&tcp_connection::handle_read_body, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
} void DEF::tcp_connection::handle_read_body(const boost::system::error_code& error,
size_t bytes_transferred)
{
//处理接收过程中的错误
if (error == boost::asio::error::eof) {
return;
}else if (error) {
std::cerr << " socket recv body error!! " << error.message()<<std::endl;
return;
}
//到达此处则接受正常 打印接受内容
//std::cout << "recv body : " << recvBuff_.GetBody() << std::endl; //todo 接受内容放入队列 另行处理 避免网络IO影响处理效率
assert(p_messageQueue_ != nullptr);
p_messageQueue_->Put(recvBuff_.GetBody()); //再次进入异步等待 进行下一次包头的接收
boost::asio::async_read(socket_, boost::asio::buffer(&recvBuff_.head, sizeof(recvBuff_.head)),
boost::bind(&tcp_connection::handle_read_head, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}

netasio.cpp

 #pragma once
#include "pre.h"
#include <boost/asio.hpp> #include "SyncQueue.h"
/*
write by def
技术博客 http://www.cnblogs.com/itdef/
技术交流群 群号码:432336863
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
部分老代码存放地点
http://www.oschina.net/code/list_by_user?id=614253
*/
NAMESPACEBEGIN(DEF)
using boost::asio::ip::tcp; class NetMgr {
public:
//单例
static NetMgr& Instance() {
static NetMgr instance;
return instance;
}
void Start(); private:
NetMgr() :p_messageQueue_(std::make_shared<SyncQueue<std::string>>()) {}
void NetThread(std::shared_ptr<SyncQueue<std::string>> pQueue);
void CommandDispatch(std::shared_ptr<SyncQueue<std::string>> pQueue);
const std::string EXITCOMMAND= "EXIT";
~NetMgr() {}
std::shared_ptr<SyncQueue<std::string>> p_messageQueue_;
boost::asio::io_service io_service_;
}; NAMESPACEEND(DEF)

netmgr.h

 #include <thread>
#include <iostream>
#include "NetMgr.h"
#include "NetAsio.h" using namespace DEF;
/*
write by def
技术博客 http://www.cnblogs.com/itdef/
技术交流群 群号码:432336863
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
部分老代码存放地点
http://www.oschina.net/code/list_by_user?id=614253
*/
void NetMgr::NetThread(std::shared_ptr<SyncQueue<std::string>> pQueue) {
assert(pQueue != nullptr);
boost::asio::io_service& io_s = io_service_;
tcp_server ts(io_s, , pQueue);
io_s.run();
} void NetMgr::CommandDispatch(std::shared_ptr<SyncQueue<std::string>> pQueue) {
assert(pQueue != nullptr);
for (int i = ; i < ; i++) {
std::string s;
pQueue->Take(s);
std::cout << s << std::endl;
} } void NetMgr::Start() {
std::thread t1 = std::thread(&NetMgr::NetThread,this, p_messageQueue_);
std::thread t2 = std::thread(&NetMgr::CommandDispatch,this, p_messageQueue_);
std::string input;
std::cout << "Input \"" << EXITCOMMAND << "\" to exit";
while (std::cin >> input)
{
//todo add command parse
if (input == EXITCOMMAND) {
break;
}
std::cout << input << std::endl;
}
t1.join();
t2.join();
}

ntmgr.cpp

如何优雅的退出是个很麻烦的问题,细节在实际工作需要在慢慢打磨

运行如图:

asio的网络通讯代码练手的更多相关文章

  1. 使用boost.asio实现网络通讯

    #include <boost/asio.hpp> #define USING_SSL //是否加密 #ifdef USING_SSL #include <boost/asio/ss ...

  2. webpack练手项目之easySlide(二):代码分割(转)

    在上一篇 webpack练手项目之easySlide(一):初探webpack  中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但是乍一看webpack ...

  3. 仿PC版微信的练手项目(可实时通讯)

    仿PC版微信的DEMO 本项目是由一个仿PC版微信的vue前端项目,和一个使用leancloud进行数据存储的.提供WebSocket的node后端项目构成. 本项目使用的技术栈:vue + vue- ...

  4. webpack练手项目之easySlide(二):代码分割

    Hello,大家好. 在上一篇 webpack练手项目之easySlide(一):初探webpack  中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但 ...

  5. python 网络通讯 服务器端代码demo,能够同时处理多个客户端的连接请求

    这是一个python网络通讯服务器端的代码demo,能够同时处理多个客户端的连接请求. from socket import * import threading from datetime impo ...

  6. 10个相见恨晚的 Java 在线练手项目

    10个有意思的Java练手项目: 1.Java 开发简单的计算器 难度为一般,适合具有 Java 基础和 Swing 组件编程知识的用户学习 2.制作一个自己的 Java 编辑器 难度中等,适合 Ja ...

  7. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  8. 10个有趣的Python教程,附视频讲解+练手项目。

    从前的日色变得慢,车.马.邮件都慢 一生只够爱一门编程语言 从前的教程也好看,画面精美有样子 你看了,立马就懂了 Python最性感的地方,就在于它的趣味性和前沿性,学习Python,你总能像科技节的 ...

  9. Java学习路径及练手项目合集

    Java 在编程语言排行榜中一直位列前排,可知 Java 语言的受欢迎程度了. 实验楼上的[Java 学习路径]中将首先完成 Java基础.JDK.JDBC.正则表达式等基础实验,然后进阶到 J2SE ...

随机推荐

  1. Missing artifact org.hibernate:hibernate-core:jar:4.3.0.Final

    Missing artifact org.hibernate:hibernate-core:jar:4.3.0.Final

  2. HTML图片热区map area的用法(转)

    <area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: 1 & ...

  3. because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled

    spring security 配置问题,静态资源未被允许访问

  4. BeautifulSoup中查找元素 select() 和find()区别

    从html中查找元素,之前一般都用find(),查找符合条件的第一个,如下 f = open(file, 'r') # 读取文件内容content = f.read()soup= BeautifulS ...

  5. hbase备份数据与异地新建

    hbase org.apache.hadoop.hbase.mapreduce.Driver export news /tmp/news1 备份news表至hdfs的/tmp目录下面. hadoop ...

  6. vue 定时器的问题

    在项目中,我们经常会使用到定时器setInterval(),可是很多时候我们会发现,即使我退出当前页面,定时器依然在工作,非常消耗内存,所以我们要进行手动清理: 将定时器保存在变量中,退出页面时清除变 ...

  7. LibreOJ 6280 . 数列分块入门 4

    题目链接:https://loj.ac/problem/6280 加一个数组保存块的和. 代码: #include<iostream> #include<cstring> #i ...

  8. leecode 978. Longest Turbulent Subarray(最长连续波动序列,DP or 滚动数组)

    传送门:点我 978. Longest Turbulent Subarray A subarray A[i], A[i+1], ..., A[j] of A is said to be turbule ...

  9. 学习Junit资料

    以下是找到的一些有用的学习资料,先收藏了 http://www.blogjava.net/jiangshachina/archive/2011/12/14/366289.html http://www ...

  10. vue项目引入FastClick组件解决IOS系统下h5页面中的按钮点击延迟,连续点击无反应的问题

    异常描述: ios系统手机中访问h5页面,按钮点击有延迟,连续点击卡顿.无反应. 异常原因: 这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设 ...