boost asio 网络聊天 代码修改学习
简化asio的聊天代码 去除ROOM的设计
所有连接客户端均在同一个ROOM下
/**************************************************************技术博客http://www.cnblogs.com/itdef/技术交流群群号码:324164944欢迎c c++ windows驱动爱好者 服务器程序员沟通交流**************************************************************/chat message 使用boost自带示例的头文件
#pragma once #include <cstdio>
#include <cstdlib>
#include <cstring> class chat_message
{
public:
enum { header_length = 4 };
enum { max_body_length = 512 }; chat_message():
body_length_(0)
{} const char* data()const
{
return data_;
} char* data()
{
return data_;
} size_t length()const
{
return header_length + body_length_;
} const char* body()const
{
return data_ + header_length;
}
char* body()
{
return data_ + header_length;
}
size_t body_length()const
{
return body_length_;
} void body_length(size_t new_length)
{
body_length_ = new_length;
if (body_length_ > max_body_length)
body_length_ = max_body_length;
} bool decode_header()
{
using namespace std;
char header[header_length + 1] = "";
strncat(header, data_, header_length);
body_length_ = atoi(header);
if (body_length_ > max_body_length)
{
body_length_ = 0;
return false;
}
return true;
} void encode_header()
{
using namespace std;
char header[header_length + 1] = "";
sprintf(header,"%4d",static_cast<int>(body_length_));
memcpy(data_,header,header_length);
} private:
char data_[header_length + max_body_length];
size_t body_length_;
};
// MyChat.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <set>
#include <iostream>
#include "chat_message.h" using namespace boost::asio::ip; const int defaultPort = 8899; class chat_session;
typedef boost::shared_ptr<chat_session> chat_session_ptr; class chat_session :
public boost::enable_shared_from_this<chat_session>
{
public:
chat_session(boost::asio::io_service& io_service, std::set<chat_session_ptr>& sessionList)
: socket_(io_service), sessionList_(sessionList)
{
} ~chat_session() { std::cout << "~chat_session()" << std::endl; }
tcp::socket& socket()
{
return socket_;
} void start()
{
sessionList_.insert(shared_from_this());
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(), chat_message::header_length),
boost::bind(
&chat_session::handle_read_header, shared_from_this(),
boost::asio::placeholders::error));
} void handle_read_header(const boost::system::error_code& error)
{
if (!error && read_msg_.decode_header() )
{
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.body(), read_msg_.body_length()),
boost::bind(&chat_session::handle_read_body, shared_from_this(),
boost::asio::placeholders::error));
}
else
{
// occur error,delete from list
sessionList_.erase(shared_from_this());
socket_.shutdown(tcp::socket::shutdown_both);
socket_.close();
return;
}
} void handle_read_body(const boost::system::error_code& error)
{
if (!error)
{
std::cout << read_msg_.data() << std::endl;
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(), chat_message::header_length),
boost::bind(&chat_session::handle_read_header, shared_from_this(),
boost::asio::placeholders::error));
}
else
{
// occur error,delete from list
sessionList_.erase(shared_from_this());
socket_.shutdown(tcp::socket::shutdown_both);
socket_.close();
return;
} } private:
char recvbuf[5];
tcp::socket socket_;
chat_message read_msg_;
std::set<chat_session_ptr>& sessionList_;
}; typedef boost::shared_ptr<chat_session> chat_session_ptr; class chat_server
{
public:
chat_server(boost::asio::io_service& io_service,
const tcp::endpoint& endpoint)
: io_service_(io_service),
acceptor_(io_service, endpoint)
{
start_accept();
} void start_accept()
{
chat_session_ptr new_session(new chat_session(io_service_, sessionList_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&chat_server::handle_accept, this, new_session,
boost::asio::placeholders::error));
} void handle_accept(chat_session_ptr session,
const boost::system::error_code& error)
{
if (!error)
{
session->start();
} start_accept();
}
private:
boost::asio::io_service& io_service_;
tcp::acceptor acceptor_;
std::set<chat_session_ptr> sessionList_;
}; typedef boost::shared_ptr<chat_server> chat_server_ptr; int main()
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(tcp::v4(), defaultPort);
chat_server chatServer(io_service, endpoint); io_service.run();
return 0;
}
测试客户端 chat_message头文件公用
// MyChatCLient.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include "chat_message.h"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> using boost::asio::ip::tcp; #define testString "this is a test string......." class chat_client:
public boost::enable_shared_from_this<chat_client>
{
public:
chat_client(boost::asio::io_service& io_service,
tcp::resolver::iterator endpoint_iterator)
: io_service_(io_service), endpoint_iterator_(endpoint_iterator),
socket_(io_service)
{ } void do_close()
{
socket_.close();
} void Start()
{
boost::asio::async_connect(socket_, endpoint_iterator_,
boost::bind(&chat_client::handle_connect, shared_from_this(),
boost::asio::placeholders::error));
} private:
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
chat_message write_msg_;
write_msg_.body_length(strlen(testString) + 1);
memcpy(write_msg_.body(), testString, write_msg_.body_length());
write_msg_.encode_header(); boost::asio::async_write(socket_,
boost::asio::buffer(write_msg_.data(),
write_msg_.length()),
boost::bind(&chat_client::handle_write, shared_from_this(),
boost::asio::placeholders::error));
}
else
{
do_close();
}
}
void handle_connect(const boost::system::error_code& error)
{
if (!error)
{
chat_message write_msg_;
write_msg_.body_length(strlen(testString)+1);
memcpy(write_msg_.body(), testString, write_msg_.body_length());
write_msg_.encode_header(); boost::asio::async_write(socket_,
boost::asio::buffer(write_msg_.data(),
write_msg_.length()),
boost::bind(&chat_client::handle_write, shared_from_this(),
boost::asio::placeholders::error));
}
else
{
do_close();
}
} private:
boost::asio::io_service& io_service_;
tcp::socket socket_;
chat_message write_msg_;
tcp::resolver::iterator endpoint_iterator_;
};
typedef boost::shared_ptr<chat_client> chat_client_ptr; int main()
{
boost::asio::io_service io_service; tcp::resolver resolver(io_service);
tcp::resolver::query query("127.0.0.1", "8899");
tcp::resolver::iterator iterator = resolver.resolve(query);
for (int i = 0; i < 100; i++)
{
chat_client_ptr a(new chat_client(io_service, iterator));
a->Start();
} io_service.run();
return 0;
}
运行效果图

关闭客户端后

boost asio 网络聊天 代码修改学习的更多相关文章
- boost asio 学习(九) boost::asio 网络封装
http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...
- Boost.Asio 网络编程([译]Boost.Asio基本原理)
转自:https://m.w3cschool.cn/nlzbw/nlzbw-3vs825ya.html Boost.Asio基本原理 这一章涵盖了使用Boost.Asio时必须知道的一些事情.我们也将 ...
- 改进基于Boost.Asio的聊天服务
Boost.Asio是个非常易用的C++异步网络库,官方文档中一个示例是聊天服务,分为chat_message.chat_client.chat_server三个部分.chat_server的启动代码 ...
- boost Asio网络编程简介
:first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-previ ...
- boost::asio网络传输错误码的一些实验结果(recv error_code)
错误码很重要,可以由此判断网络连接到底发生了神马事情,从而驱动高层逻辑的行为.只有笼统的错误码判断的网络层是不够规范的,鄙人觉得有些错误码还是需要在网络层就区分开的,特此记录一些当前实验的错误码以及发 ...
- boost asio 一个聊天的基本框架
示例代码 #include "Util.h" #include "MyAsio.h" #include "TcpConnectionManager.h ...
- boost::asio译文
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...
- Boost.Asio技术文档
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...
- boost::asio::io_service类
大部分使用Boost.Asio编写的代码都会使用几个io_service的实例.io_service是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用其完 ...
随机推荐
- python永久添加环境变量
import sys sys.path 系统环境是一个list,可以将自己需要的库添加进入,例如mysql库,hive库等等.有三种方式添加,均验证通过: 1 临时添加,在一个shell窗口中 ...
- Kong管理UI -kong-dashboard
本文仍然是在ubuntu18的环境下进行 https://github.com/PGBI/kong-dashboard kong dashboart如果要正常使用管理UI,前提为kong已经正常run ...
- 6.8 出口条件循环:do while
while循环和for循环都是入口条件循环,即在循环的每次迭代之前检查测试条件,所以有可能根本不执行循环体中的内容.C语言还有出口条件循环(exit-condition loop),即在循环的每次迭代 ...
- k8s学习笔记之四:资源清单定义入门
第一章.k8s中的资源 1.什么叫资源? k8s中所有的内容都抽象为资源, 资源实例化之后,叫做对象 2.在k8s中有哪些资源? 工作负载型资源(workload): Pod ReplicaSet D ...
- ScrollView滑动到底部或顶部监听,ScrollView滑动到底部或顶部再继续滑动监听;
ScrollView滑动到底部或顶部后,再继续滑动达到一定距离的监听: ScrollView滑动到底部或顶部的监听: /** * 监听ScrollView滚动到顶部或者底部做相关事件拦截 */ pub ...
- JS截取URL地址参数
var url = window.location.search; 截取?r= 后面的参数var url = window.location.href;var urlss= urlssplit('co ...
- [Linux] traceroute 路由跟踪指令用例
traceroute是用来跟踪数据包到达网络主机所经过的路由工具.在Linux系统中,称之为traceroute,在Windows中称为tracert. 一条路径上的每个设备traceroute要测3 ...
- canvas 2.0 图片绘制
绘制图片drawImage 2013.02.21 by 十年灯·一条评论 本文属于<html5 Canvas画图系列教程> 这里的绘制图片是指把一张现成的图片,绘制到Canvas上面. 有 ...
- python练习题_01
1.执行python的两种方式 答:1.通过解释器执行1.py 2.通过cmd执行python,再执行1.py 2.简述位与字节的的关系 答:8位=1字节(计算机处理时以字节为单位,存储时以位为单位) ...
- 下载安装 STS(Spring Tool Suite),推荐对应 Eclipse 版本号,适用于Windows32位(xp、2003)
sts下载地址:https://spring.io/tools/sts/legacy 虽然sts内置了版本对应的eclipse,仍推荐使用当前环境下稳定使用的eclipse版本. Start 找到ec ...