深入应用c++11 随书代码

代码并未在作者github上提供

将书中代码敲至vc 并调试运行

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

  

时间: 2024-10-11 09:01:55

深入应用c++11 随书代码的相关文章

C++11的thread代码分析

本文分析的是llvm libc++的实现:http://libcxx.llvm.org/ class thread thread类直接包装了一个pthread_t,在linux下实际是unsigned long int. class thread { pthread_t __t_; id get_id() const _NOEXCEPT {return __t_;} } 用了一个std::unique_ptr来包装用户定义的线程函数: 创建线程用的是 template <class _Fp>

Cocos2d-x手机游戏开发与项目实践具体解释_随书代码

Cocos2d-x手机游戏开发与项目实战具体解释_随书代码 作者:沈大海  因为原作者共享的资源为UTF-8字符编码.下载后解压在win下显示乱码或还出现文件不全问题,现完整整理,解决全部乱码问题,供大家下载. 下载地址:http://download.csdn.net/detail/oyangyufu/7665049

Cocos2d-x手机游戏开发与项目实践详解_随书代码

Cocos2d-x手机游戏开发与项目实战详解_随书代码 作者:沈大海  由于原作者共享的资源为UTF-8字符编码,下载后解压在win下显示乱码或还出现文件不全问题,现完整整理,解决所有乱码问题,供大家下载. 下载地址:http://download.csdn.net/detail/oyangyufu/7665049 Cocos2d-x手机游戏开发与项目实践详解_随书代码

《Lucene实战(第2版)》 配书代码在IDEA下的编译方法

参考: hankcs http://www.hankcs.com/program/java/lucene-combat-2nd-edition-book-with-code-compiled-under-the-idea.html 最基础的Ant编译: 点击右边的加号载入lia2e下的build.xml脚本,接着在列表里双击某单元对应的程序就行了: 通过IDEA Configuration编译运行: 新建一个控制台配置,选择主类: 编译运行报错: java: 找不到符号 符号:   方法 nex

《C++编程思想》 第十三章 继承和组合 (原书代码+习题+解答)

一.相关知识 使用其他人已经创建并调试过的类: 关键是使用类而不是更改已存在的代码.这一章将介绍两种完成这件事的方法.第一种方法是很直接的:简单地创建一个包含已存在的类对象的新类,这称为组合,因为这个新类是由已存在类的对象组合的. 第二种方法更巧妙,创建一个新类作为一个已存在类的类型,采取这个已存在类的形式,对它增加代码,但不修改它.这个有趣的活动被称为继承,其中大量的工作由编译器完成.继承是面向对象程序设计的基石,并且还有另外的含义,将在下一章中探讨. 对于组合和继承(感觉上,它们都是由已存在

Git-2.11.1-64-bit.exe 代码管理工具使用

下载并安装:Git-2.11.1-64-bit.exe 1.找到桌面>>右键>>打开Git Bash here 控制台 2.输入下面几条命令 初始化git环境:git config --global user.name "qiweb_vps" git config --global user.email "[email protected]" git init Initialized empty Git repository in C:/Us

u-boot-2014.10移植第11天----深入分析代码(六)

硬件平台:tq2440 开发环境:Ubuntu-3.11 u-boot版本:2014.10 本文允许转载,请注明出处:http://blog.csdn.net/fulinus "从relocate_code回到_main中,接下来是main最后一段代码"也就是arch/arm/lib/crt0.S文件中: b   relocate_codehere://从这里开始u-boot已经在重定位的地方运行了 /* Set up final (full) environment */ bl  c

一个 11 行 Python 代码实现的神经网络

概要:直接上代码是最有效的学习方式.这篇教程通过由一段简短的 python 代码实现的非常简单的实例来讲解 BP 反向传播算法. 代码如下: Python 1 2 3 4 5 6 7 8 9 10 11 X = np.array([ [0,0,1],[0,1,1],[1,0,1],[1,1,1] ]) y = np.array([[0,1,1,0]]).T syn0 = 2*np.random.random((3,4)) - 1 syn1 = 2*np.random.random((4,1))

【资源分享】CLR.via.C#(第3版)英文原版+中文译本+随书代码

看完了<叩响C#之门>,并利用学到了知识解决了工作中的一个麻烦. 觉得C#没有想象中那么难,于是打算进一步学好它. 这几天在四处请教好书推荐. 毕竟对于我来说,没有那么多时间用来自己寻找教材. 有不少热心的朋友向我推荐了许多书籍,我也都一一找来看了看. 最终,我决定看<CLR.via.C#(第3版)> 它或许更适合我目前的阶段,而设计模式之类的对我来说还有点早. 中午在亚马逊买了中文版,但始终不太放心,觉得还是能有英文原版对照会更容易理解. 根据我的经验,有时候英文会比中文更好理解