boost asio 网络聊天 代码修改学习

简化asio的聊天代码 去除ROOM的设计

所有连接客户端均在同一个ROOM下

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;
}

  

时间: 2024-10-10 21:50:04

boost asio 网络聊天 代码修改学习的相关文章

Boost Asio 网络编程 基本用法

Boost Asio 网络编程 基本用法 flyfish 2015-2-9 IP地址 boost::asio::ip::address表示IP地址,同时支持ipv4和ipv6. boost::asio::ip::address addr; addr = addr.from_string("127.0.0.1"); assert(addr.is_v4()); OutputDebugStringA(addr.to_string().c_str()); addr = addr.from_st

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

错误码很重要,可以由此判断网络连接到底发生了神马事情,从而驱动高层逻辑的行为.只有笼统的错误码判断的网络层是不够规范的,鄙人觉得有些错误码还是需要在网络层就区分开的,特此记录一些当前实验的错误码以及发生原因. 以下是一部分在async_receive()的handler处捕获到的比较有用的错误码 错误码(十进制) 枚举 发现原因 10009 boost::asio::error::bad_descriptor 在一个已经关闭了的套接字上执行async_receive() 995 boost::a

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 network wrapper (TCP) 现在我们了解asio和TCP网络方面的知识,我们可以尝试下封装网络底层.通过使用这个封装,我们可以重用代码并且将精力集中于业务逻 辑方面而不在网络通讯方面花费太多精力. 重要提示:本代码仅仅用于教学目的.不要在商业系统中使用该代码,

C/C++利用Boost::Asio网络库建立自己的Socket服务器

引言 寸光阴,当下我们或许更需要利用现有的知识,应用现有的技术.网络是当前互联网的根本,了解网络便开始显得极其重要.今天我们利用Boost库中Asio部分,浅尝网络服务器.此处不做过于深入的开展,为达成学习目的,只做简单的异步并发服务器. 注意:本篇代码没有直接引用boost等命名空间,为的是新入门Boost的同学能够更好的了解每个参数在boost的具体命名空间位置,有助于更好的理解boost的布局. 版权所有:_OE_,转载请注明出处:http://blog.csdn.net/csnd_ayo

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

Boost.Asio是个非常易用的C++异步网络库,官网上有很详细文档和示例代码.其中一个示例是聊天服务,分成chat_message.chat_client.chat_server这么三个部分.chat_server的启动代码如下. 1 if (argc < 2) 2 { 3 std::cerr << "Usage: chat_server <port> [<port> ...]\n"; 4 return 1; 5 } 6 7 boost::

boost Asio网络编程简介

.markdown-preview:not([data-use-github-style]) { padding: 2em; font-size: 1.2em; color: rgb(171, 178, 191); background-color: rgb(40, 44, 52); overflow: auto } .markdown-preview:not([data-use-github-style])>:first-child { margin-top: 0px } .markdown-

Boost.Asio c++ 网络编程翻译(6)

io_service类 你应该已经发现大部分使用Boost.Asio编写的代码都会使用几个ios_service的实例.ios_service是这个库里面最重要的类:它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用完成处理程序. 如果你选择用同步的方式来创建你的应用,你不需要考虑我将在这一节向你展示的东西. 你可以用几种不同的方式来使用io_service.在下面的例子中,我们有3个异步操作,2个socket连接和一个计时器等待: 有一个io_service和一个处理线程

Boost.Asio技术文档

Christopher Kohlhoff Copyright ? 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_0.txt文件或从http://www.boost.org/LICENSE_1_0.txt) Boost.Asio是用于网络和低层IO编程的跨平台C++库,为开发者提供了C++环境下稳定的异步模型. 综述 基本原理 应用程序与外界交互的方式有很多,可通过文件,网络,串口或控制台.例如在网络通信中,完

boost::asio译文

Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_0.txt文件或从http://www.boost.org/LICENSE_1_0.txt) Boost.Asio是用于网络和低层IO编程的跨平台C++库,为开发者提供了C++环境下稳定的异步模型. 综述 基本原理 应用程序与外界交互的方式有很多,可通过文件,网络,串口或控制台.例如在网络通信中,完