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是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用其完 ...
随机推荐
- linux系统常用的基本命令分类
linux系统常用的基本命令分类: 文件命令:vim vimdiff diff mkdir touch rm mv cp ln cd ls more less head tail cat grep e ...
- ftp 和vsftp
内置sftp:https://blog.csdn.net/xinxin19881112/article/details/46831311 vsftp:http://blog.51cto.com/cui ...
- C++Primer第五版——习题答案详解(四)
习题答案目录:https://www.cnblogs.com/Mered1th/p/10485695.html 第5章 语句 练习5.9 #include<iostream> #inclu ...
- c# 抽象类 抽象函数 接口
抽象类与抽象方法: 被abstract关键字修饰的类叫做抽象类 被abstract关键字修饰的方法叫做抽象方法 1.抽象方法必须放在抽象类中 2.抽象方法不可以实现代码,用空语句替代 3.抽象方法可以 ...
- ssl协议相关
<1> SSL版本 测试浏览器支持的SSL版本的网站: https://www.ssllabs.com/ssltest/viewMyClient.html 0xfefd (DTLS ...
- [二维码开发]二维码开发入门级demo
最近开发一个项目,涉及到二维码开发,于是乎就到网上找下直接可用的资源,遇到两个问题: 1.网上资源不够完整,找到完整的资源,需要下载分,这个你知道的 2.ThoughtWorks.QRCode版本不对 ...
- python学习笔记之四-多进程&多线程&异步非阻塞
ProcessPoolExecutor对multiprocessing进行了高级抽象,暴露出简单的统一接口. 异步非阻塞 爬虫 对于异步IO请求的本质则是[非阻塞Socket]+[IO多路复用]: & ...
- vue展示dicom文件,医疗系统。
环境:vue.webpack.constone 资料来源及文件:https://github.com/GleasonBian/CornerstoneVueWADO 需要下载的模块:cornerston ...
- 权限管理demo-Http请求前后监听工具
工具作用: 1. 输出每次请求的参数 2. 接口的请求时间 package com.mmall.common; import com.mmall.util.JsonMapper; import lom ...
- JAVA性能优化:35个小细节让你提升java代码的运行效率
代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...