zoukankan      html  css  js  c++  java
  • 深入应用c++11 随书代码

    代码并未在作者github上提供

    将书中代码敲至vc 并调试运行 依赖BOOST库 

    编译环境vs2015 boost1.59

    // Client.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <boost/thread.hpp>
    #include <thread>
    #include <string>
    #include "../Common/RWHandler.h"
    
    class Connector
    {
    public:
    	Connector(io_service& ios, const string& strIp, short port) :m_ios(ios), m_socket(ios),
    		m_serverAddr(tcp::endpoint(address::from_string(strIp), port)), m_isConnected(false),
    		m_chkThread(nullptr)
    	{
    		CreateEventHandler(ios);
    	}
    	~Connector(){}
    	bool Start()
    	{
    		m_eventHandler->GetSocket().async_connect(m_serverAddr, [this](const boost::system::error_code& error)
    		{
    			if (error)
    			{
    				HandleConnectError(error);
    				return;
    			}
    			cout << "connect ok" << endl;
    			m_isConnected = true;
    			m_eventHandler->HandleRead();
    		});
    		boost::this_thread::sleep(boost::posix_time::seconds(1));
    		return m_isConnected;
    	}
    
    	bool IsConnected()const
    	{
    		return m_isConnected;
    	}
    
    	void Send(char* data, int len)
    	{
    		if (!m_isConnected)
    			return;
    		m_eventHandler->HandleWrite(data,len);
    	}
    
    	void AsyncSend(char* data, int len)
    	{
    		if (!m_isConnected)
    			return;
    		//m_eventHandler->HandleAsyncWrite(data, len);
    		m_eventHandler->HandleWrite(data, len);
    	}
    private:
    	void CreateEventHandler(io_service& ios)
    	{
    		m_eventHandler = std::make_shared<RWHandler>(ios);
    		m_eventHandler->SetCallBackError([this](int connid) { HandleRWError(connid); });
    	}
    
    	void CheckConnect()
    	{
    		if (m_chkThread != nullptr)
    			return;
    		m_chkThread = std::make_shared<std::thread>([this]
    		{
    			while (true)
    			{
    				if (!IsConnected())
    					Start();
    				boost::this_thread::sleep(boost::posix_time::seconds(1));
    			}
    		});
    	}
    
    	void HandleConnectError(const boost::system::error_code& error)
    	{
    		m_isConnected = false;
    		cout << error.message() << endl;
    		m_eventHandler->CloseSocket();
    		CheckConnect();
    	}
    
    	void HandleRWError(int connid)
    	{
    		m_isConnected = false;
    		CheckConnect();
    	}
    private:
    	io_service& m_ios;
    	tcp::socket m_socket;
    
    	tcp::endpoint m_serverAddr;
    
    	std::shared_ptr<RWHandler> m_eventHandler;
    	bool m_isConnected;
    	std::shared_ptr<std::thread> m_chkThread;
    };
    
    int main()
    {
    	io_service ios;
    	boost::asio::io_service::work work(ios);
    	boost::thread thd([&ios] {ios.run(); });
    
    	Connector conn(ios, "127.0.0.1", 9900);
    	conn.Start();
    	std::string str;
    	if (!conn.IsConnected())
    	{
    		cin >> str;
    		return -1;
    	}
    
    	const int len = 512;
    	char line[len] = "";
    
    	while (cin >> str)
    	{
    		char header[HEAD_LEN] = {};
    		int totalLen = str.length() + 1 + HEAD_LEN;
    		std::sprintf(header, "%d", totalLen);
    		memcpy(line, header, HEAD_LEN);
    		memcpy(line + HEAD_LEN, str.c_str(), str.length() + 1);
    		conn.Send(line, totalLen);
    
    	}
    
        return 0;
    }
    

      

    // Server.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "../Common/RWHandler.h"
    #include "../Common/Message.h"
    
    #include <boost/asio/buffer.hpp>
    #include <unordered_map>
    #include <numeric>
    
    const int MaxConnectionNum = 65536;
    const int MaxRecvSize = 65536;
    class Server {
    public:
    	Server(io_service& ios, short port) :m_ios(ios), m_acceptor(ios, tcp::endpoint(tcp::v4(), port)),
    		m_connIdPool(MaxConnectionNum)
    	{
    		m_connIdPool.resize(MaxConnectionNum);
    		std::iota(m_connIdPool.begin(), m_connIdPool.end(), 1);
    	}
    
    	~Server(){}
    
    	void Accept()
    	{
    		cout << "Start listening " << endl;
    		std::shared_ptr<RWHandler> handler = CreateHandler();
    
    		m_acceptor.async_accept(handler->GetSocket(), [this, handler](const boost::system::error_code& error)
    		{
    			if (error)
    			{
    				cout << error.value() << " " << error.message() << endl;
    				HandleAcpError(handler, error);
    				return;
    			}
    			m_handlers.insert(std::make_pair(handler->GetConnId(),handler));
    			cout << "current connect count: " << m_handlers.size() << endl;
    
    			handler->HandleRead();
    			Accept();
    		});
    	}
    
    private:
    	void HandleAcpError(std::shared_ptr<RWHandler> eventHandler, const boost::system::error_code& error)
    	{
    		cout << "Error,error reason: " << error.value() << error.message() << endl;
    		eventHandler->CloseSocket();
    		StopAccept();
    	}
    
    	void StopAccept()
    	{
    		boost::system::error_code ec;
    		m_acceptor.cancel(ec);
    		m_acceptor.close(ec);
    		m_ios.stop();
    	}
    
    	std::shared_ptr<RWHandler> CreateHandler()
    	{
    		int connId = m_connIdPool.front();
    		m_connIdPool.pop_front();
    		std::shared_ptr<RWHandler> handler = std::make_shared<RWHandler>(m_ios);
    		handler->SetConnId(connId);
    		handler->SetCallBackError([this](int connId)
    		{
    			RecyclConnid(connId);
    		});
    		return handler;
    	}
    
    	void RecyclConnid(int connId)
    	{
    		auto it = m_handlers.find(connId);
    		if (it != m_handlers.end())
    			m_handlers.erase(it);
    		//==
    		cout << "current connect count: " << m_handlers.size() << endl;
    		m_connIdPool.push_back(connId);
    	}
    private:
    	io_service& m_ios;
    	tcp::acceptor m_acceptor;
    	std::unordered_map<int, std::shared_ptr<RWHandler>> m_handlers;
    	list<int> m_connIdPool;
    
    };
    
    
    int main()
    {
    	io_service ios;
    
    	Server server(ios, 9900);
    	server.Accept();
    	ios.run();
    
        return 0;
    }
    

      

    #pragma once
    
    class Message {
    public:
    	enum { header_length = 4 };
    	enum { max_body_length = 512 };
    
    	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()
    	{
    		char header[header_length + 1] = "";
    		std::strncat(header, data_, header_length);
    		body_length_ = std::atoi(header) - header_length;
    		if (body_length_ > max_body_length)
    		{
    			body_length_ = 0;
    			return false;
    		}
    		return true;
    	}
    
    	void encode_header()
    	{
    		char header[header_length + 1] = "";
    		std::sprintf(header,"%4d",body_length_);
    		std::memcpy(data_,header,header_length);
    	}
    private:
    	char data_[header_length + max_body_length];
    	std::size_t body_length_;
    };
    

      

    #pragma once
    #include <array>
    #include <functional>
    #include <iostream>
    
    using namespace std;
    
    #include <boost/asio.hpp>
    using namespace boost::asio;
    using namespace boost::asio::ip;
    using namespace boost;
    
    const int MAX_IP_PACK_SIZE = 65536;
    const int HEAD_LEN = 4;
    
    class RWHandler {
    public:
    	RWHandler(io_service& ios) :m_sock(ios) {}
    	~RWHandler(){}
    	void HandleRead() {
    		async_read(m_sock, buffer(m_buff), transfer_at_least(HEAD_LEN), [this](const boost::system::error_code& ec,
    			size_t size) {
    			if (ec != nullptr)
    			{
    				HandleError(ec);
    				return;
    			}
    			cout << m_buff.data() + HEAD_LEN << endl;
    			HandleRead();
    		});
    	}
    
    	void HandleWrite(char* data, int len)
    	{
    		boost::system::error_code ec;
    		write(m_sock, buffer(data, len), ec);
    		if (ec != nullptr)
    			HandleError(ec);
    	}
    
    	tcp::socket& GetSocket() { return m_sock; }
    
    	void CloseSocket()
    	{
    		boost::system::error_code ec;
    		m_sock.shutdown(tcp::socket::shutdown_send, ec);
    		m_sock.close(ec);
    	}
    
    	void SetConnId(int connId) { m_connId = connId; }
    
    	int GetConnId()const { return m_connId; }
    
    	template<typename F>void SetCallBackError(F f) { m_callbackError = f; }
    
    private:
    	void HandleError(const boost::system::error_code& ec)
    	{
    		CloseSocket();
    		cout << ec.message() << endl;
    		if (m_callbackError)
    			m_callbackError(m_connId);
    	}
    
    private:
    	tcp::socket m_sock;
    	std::array<char, MAX_IP_PACK_SIZE> m_buff;
    	int m_connId;
    	std::function<void(int)> m_callbackError;
    };
    

      

  • 相关阅读:
    2008年10月小记(SQL删除重复记录,生成表结构,字符串特性,statistics io)
    mysql 中 @
    使用单个innodb表,实现锁,防止游戏被刷物品或者其它资源!
    PSL
    8年PHP,懂点内核, 能写PHP扩展,5年网站经历+3年webgame经历,找个兼职
    Php aes算法
    MySQL触发器自动更新memcache
    怎么配置MySQL服务器(Incorrect string value)
    使用 PHP 将 XML 转化为易读的数组!
    使用Valgrind 查找内存泄露
  • 原文地址:https://www.cnblogs.com/itdef/p/5248823.html
Copyright © 2011-2022 走看看