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是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用其完 ...
随机推荐
- .NET 定时执行任务解决方案(Timer & Quartz.Net)
共有两种方法: 一.使用Timer global.asax <%@ Application Language="C#" %> <%@ import Namespa ...
- selenium +chromdriver模块
1 selenium 模拟浏览器行为 2 chromdriver 对应的chrome浏览器驱动 下载地址 注意:chrome与chromdriver存在对应关系 以下错误就可能是版本不对应 ...
- Node学习笔记(三)
1.EventEmitter常用的API EventEmitter.on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数 listener. E ...
- java编程思想(1)--对象导论
对象导论: 1.1 抽象过程 所有的语言都有抽象机制,抽象是解决复杂问题的根本方法.例如:汇编语言是对底层机器的轻微抽象.命令式语言(如:FORTRAN.BASIC.C)又是对汇编语言的抽象. jav ...
- 记一个jquery 无缝轮播的制作方法
接触前端也很久了,今天才发现,要做好一个轮播,其实有很多东西需要考虑进去,否则做出来的轮播效果并不好,下面我就来做一个轮播,是依赖jquery来写的 1.要做轮播,首先需要的是HTML的内容,css的 ...
- 30个php操作redis常用方法代码例子(转载)
1.connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE示例: $redis = new red ...
- json 异常
com.google.gson.JsonSyntaxException: 1530842820000 1530842820000 是服务器直接返回的Date值由 Gson 解析后出来的值. 后台发出: ...
- keil mdk5安装
- MFC笔记3
1. C6有默认的提示代码功能,但是其默认的快捷键是Ctrl + Space,这一般情况下是切换输入法快捷键,所以,只需重新设置一下快捷键就可以实现提示代码功能,具体设置位置如下: 工具(T) -&g ...
- grabcut mask
#include "opencv2/opencv.hpp" using namespace cv; void main() { Mat src = imread("E:\ ...