代码并未在作者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;
};

  

最新文章

  1. openssl evp RSA 加密解密
  2. 关于WPF中RichTextBox失去焦点后如何保持高亮显示所选择的内容
  3. JSP中request getParameter和getAttribute不同(转载)
  4. Mysql备份系列(2)--mysqldump备份(全量+增量)方案操作记录
  5. RPI学习--wiringpi_API
  6. POJ 1815 Friendship ★(字典序最小点割集)
  7. ACM俱乐部算法基础练习赛(1)
  8. Swift开发学习(两):Playground
  9. How to solve java.net.SocketTimeoutException:60000millis problem in HDFS
  10. mysql too many connections 问题
  11. CentOS6下安装git
  12. SVN与Git
  13. React框架 dva 和 mobx 的使用感受
  14. 【BZOJ 2844】: albus就是要第一个出场
  15. 51nod1236 序列求和 V3
  16. MongoDB 学习使用
  17. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
  18. C99特性
  19. [转]JSP中EL表达式三元运算符的使用
  20. Explaining Delegates in C# - Part 5 (Asynchronous Callback - Way 2)

热门文章

  1. [CoentOS] MySQL删除和安装
  2. hbase权限管理
  3. JAVA 文件与base64之间的转化, 以及Web实现base64上传文件
  4. ajax方式表单拦截
  5. VS 类快捷键
  6. Python之filter函数
  7. python2限制函数传入的关键字参数
  8. Python——序列
  9. RedisTemplate Redis 操作
  10. MySql log_bin