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. Building and using plug-ins for Android

    [Building and using plug-ins for Android] 1.AAR plug-ins and Android Libraries Android Archive (AAR) ...

  2. javascript学习笔记(九):DOM操作HTML的各种方法使用

    <!DOCTYPE html> <html> <head lang="en"> <meta chaset="UTF-8" ...

  3. PHP 在 Mac 的安装之路

    半年前本以为有一些 Apache 和 PHP 的安装经验,今天在 Mac 上还是踩了很多坑. 坦诚地讲,这东西入门成本比 Node,Python 入门成本真的是大很多. Apache 的编译安装就是那 ...

  4. AttributeError: 'dict' object has no attribute 'iteritems'

    在python3.6中运行 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse= ...

  5. RocketMq --consumer自动实现负载均衡

    这边使用一个producer和两个consumer是实现负载均衡. 看一下代码示例 package com.alibaba.rocketmq.example.message.model; import ...

  6. TZOJ 1221 Tempter of the Bone(回溯+剪枝)

    描述 The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked i ...

  7. iOS - 抖音效果

    抖音的转场动画—iOS https://www.jianshu.com/p/29b0165de712 抖音的上下滑实现—iOS https://www.jianshu.com/p/e8799510c7 ...

  8. ReactPHP── PHP版的Node.js(转)

    原文地址:http://www.csdn.net/article/2015-10-12/2825887 摘要:ReactPHP作为Node.js的PHP版本.在实现思路,使用方法,应用场景上的确有很多 ...

  9. Java反射获取对象VO的属性值(通过Getter方法)

    有时候,需要动态获取对象的属性值. 比如,给你一个List,要你遍历这个List的对象的属性,而这个List里的对象并不固定.比如,这次User,下次可能是Company. e.g. 这次我需要做一个 ...

  10. delete,truncate 和 delete之间的区别

    1.首先看下语法定义: drop table_name truncate table_name delete table_name [where column_name = value] 2.各个删除 ...