zoukankan      html  css  js  c++  java
  • 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;
    }
    

      运行效果图

    关闭客户端后

  • 相关阅读:
    20145220韩旭飞《网络对抗》第一周学习
    学号20145220假期复习
    最简单易懂的Idea搭建SSM项目过程和配置(文末有demo哦)
    Navicate快捷键
    String.format()方法
    tomcat点击startup.bat出现闪退
    Shiro使用总结
    layer弹出层icon图标记录
    传统javabean与spring中的bean的区别【转】
    在Spring + SpringMVC + mybatis架构的项目基础上集成Shiro
  • 原文地址:https://www.cnblogs.com/itdef/p/5323615.html
Copyright © 2011-2022 走看看