简化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 网络聊天 代码修改学习的更多相关文章

  1. boost asio 学习(九) boost::asio 网络封装

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...

  2. Boost.Asio 网络编程([译]Boost.Asio基本原理)

    转自:https://m.w3cschool.cn/nlzbw/nlzbw-3vs825ya.html Boost.Asio基本原理 这一章涵盖了使用Boost.Asio时必须知道的一些事情.我们也将 ...

  3. 改进基于Boost.Asio的聊天服务

    Boost.Asio是个非常易用的C++异步网络库,官方文档中一个示例是聊天服务,分为chat_message.chat_client.chat_server三个部分.chat_server的启动代码 ...

  4. boost Asio网络编程简介

    :first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-previ ...

  5. boost::asio网络传输错误码的一些实验结果(recv error_code)

    错误码很重要,可以由此判断网络连接到底发生了神马事情,从而驱动高层逻辑的行为.只有笼统的错误码判断的网络层是不够规范的,鄙人觉得有些错误码还是需要在网络层就区分开的,特此记录一些当前实验的错误码以及发 ...

  6. boost asio 一个聊天的基本框架

    示例代码 #include "Util.h" #include "MyAsio.h" #include "TcpConnectionManager.h ...

  7. boost::asio译文

        Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...

  8. Boost.Asio技术文档

    Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...

  9. boost::asio::io_service类

    大部分使用Boost.Asio编写的代码都会使用几个io_service的实例.io_service是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用其完 ...

随机推荐

  1. AttributeError: 'module' object has no attribute 'main'

    本机环境:ubuntu16.04,  ros-kinetic $ roscore 报错 Traceback (most recent call last): File , in <module& ...

  2. ubuntu16.04 安装最新版nodejs

    ubuntu软件仓库中自带的nodejs版本过低 $ apt-cache policy nodejs nodejs: Installed: (none) Candidate: 4.2.6~dfsg-1 ...

  3. Js将数字转化为中文大写

    function number_chinese(str) { var num = parseFloat(str); var strOutput = "", strUnit = '仟 ...

  4. CSS的background

    .block{ width: 200px; height: 200px; padding: 25px; background-image:linear-gradient(#58a,#58a) ,lin ...

  5. Spring系列博客汇总

    https://www.cnblogs.com/leeSmall/category/1093236.html   springmvc https://www.cnblogs.com/leeSmall/ ...

  6. 第三章 FFmpeg转封装

    3.1 音视频文件转MP4格式 在互联网常见的格式中,跨平台最好的应该是MP4文件. 3.1.1 MP4格式标准介绍 MP4文件由多个Box与FullBox组成 每个Box由Header和Data两部 ...

  7. wordpress 解决文章内http链接问题

    1. 登录Wordpress后台, 常规设置  > 里面把站点URL 修改成 https开头 2. 登录phpmyadmin , 执行替换链接的SQL 替换wordpress配置的链接地址 (可 ...

  8. android 开发 View _2_ View的属性动画ObjectAnimator ,动画效果一览

    支持:https://www.cnblogs.com/whoislcj/p/5738478.html translationX的效果: protected void onCreate(Bundle s ...

  9. 分布式计算课程补充笔记 part 3

    ▶ OpenMP 的任务并行 (task parallelism):显式定义一系列可执行的任务及其相互依赖关系,通过任务调度的方式多线程动态执行,支持任务的延迟执行 (deferred executi ...

  10. MongoError: no primary found in replicaset

    nodejs连接mongodb时,使用集群方式报错 2017-09-22T01:42:32.115Z - error: db connect failed 2017-09-22T01:42:32.12 ...