socket连接池SocketPool分析(七):server连接池与client连接池
来源:互联网 发布:java超市收银管理系统 编辑:程序博客网 时间:2024/06/03 21:30
从我的个人博客http://xiongjun.info/2015/12/08/socket7/转过来的。
server连接池:
我在 第一篇文章socket连接池SocketPool分析(一): 概述 当中说了,服务器端有成熟的one loop per thread模型来提供高并发,这点可以仔细阅读陈硕老师的书《Linux多线程服务端编程》,server端使用socket连接池是没有什么意义的。所以我在这里就不贴代码了,避免占用空间,有兴趣的请访问server连接池的github地址
client连接池:
池里面主要的无非就是选择存储数据的数据结构。
必须有的函数也就这5个:
- 构造函数:初始化池,将数据全放入池当中(也有的设计把这个独立出一个函数)
- 析构函数:将池中的数据依照次序释放给操作系统,最后将池清空
- Dump函数:把池中的所有数据都打印出来
- GetConnection函数:从池当中获取数据
- ReleaseConnection函数:释放数据还给池
这里还加上了判断池是否为空的函数。
我的数据库连接池DBPool的设计也和这个是一样的。
#include "SocketPool/client_connection_pool.h"#include <iostream>#include <stdlib.h>#include <boost/property_tree/ptree.hpp>#include <boost/property_tree/xml_parser.hpp>#include <boost/property_tree/json_parser.hpp>#include <boost/typeof/typeof.hpp>#include <boost/foreach.hpp>#include <boost/lexical_cast.hpp>using std::cout;using std::endl;ClientPool::ClientPool() { //这里我使用boost来解析xml和json配置文件,也可以使用rapidxml或者rapidjson // 从配置文件socket.xml当中读入mysql的ip, 用户, 密码, 数据库名称, boost::property_tree::ptree pt; const char* xml_path = "../config/socket.xml"; boost::property_tree::read_xml(xml_path, pt); //client_map BOOST_AUTO(childClient, pt.get_child("Config.Client")); for (BOOST_AUTO(pos, childClient.begin()); pos!= childClient.end(); ++pos) { BOOST_AUTO(nextchild, pos->second.get_child("")); for (BOOST_AUTO(nextpos, nextchild.begin()); nextpos!= nextchild.end(); ++nextpos) { if (nextpos->first == "IP") clientConnectHost_ = nextpos->second.data(); if (nextpos->first == "Port") clientConnectPort_ = boost::lexical_cast<int>(nextpos->second.data()); if (nextpos->first == "max_connections") clientPoolSize_ = boost::lexical_cast<int>(nextpos->second.data()); } // 构造函数的作用就是根据poolSize的大小来构造多个映射 // 每个映射的连接都是同样的host,port,backlog for (int i=0; i<clientPoolSize_; ++i) { SocketObjPtr conn(new SocketObj(clientConnectHost_, clientConnectPort_)); //只有server启动了,client的connect才会成功 if (conn->Connect()) { char stringPort[10]; snprintf(stringPort, sizeof(stringPort), "%d", clientConnectPort_); string key = clientConnectHost_ + "###" + stringPort; client_map.insert(make_pair(key, conn)); } else { strErrorMessage_ = conn->ErrorMessage(); } } } /** * 由于json当中使用数组来保存Connection,这里不能通用代码 * 这段注释的代码是读取json配置文件的 const char* json_path = "../config/socket.json"; boost::property_tree::read_json(json_path, pt); //client_map BOOST_AUTO(childClient, pt.get_child("Config.Client")); for (BOOST_AUTO(pos, childClient.begin()); pos!= childClient.end(); ++pos) { BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pos->second.get_child("")) { BOOST_AUTO(nextchild, v.second.get_child("")); for (BOOST_AUTO(nextpos, nextchild.begin()); nextpos!= nextchild.end(); ++nextpos) { if (nextpos->first == "IP") clientConnectHost_ = nextpos->second.data(); if (nextpos->first == "Port") clientConnectPort_ = boost::lexical_cast<int>(nextpos->second.data()); if (nextpos->first == "max_connections") clientPoolSize_ = boost::lexical_cast<int>(nextpos->second.data()); } for (int i=0; i<clientPoolSize_; ++i) { SocketObjPtr conn(new SocketObj(clientConnectHost_, clientConnectPort_)); //只有server启动了,client的connect才会成功 if (conn->Connect()) { char stringPort[10]; snprintf(stringPort, sizeof(stringPort), "%d", clientConnectPort_); string key = clientConnectHost_ + "###" + stringPort; client_map.insert(make_pair(key, conn)); } else { strErrorMessage_ = conn->ErrorMessage(); } } } } */}ClientPool::~ClientPool() { //析构函数做的工作是轮询map,让每个连接都close掉 //再close掉client for (multimap<string, SocketObjPtr>::iterator sIt = client_map.begin(); sIt != client_map.end(); ++sIt) { sIt->second->Close(); }}/** * Dump函数,专业debug30年! */void ClientPool::Dump() const { printf("\n=====ClientPool Dump START ========== \n"); printf("clientConnectHost_=%s ", clientConnectHost_.c_str()); printf("clientConnectPort_=%d ", clientConnectPort_); printf("clientPoolSize_=%d ", clientPoolSize_); printf("strErrorMessage_=%s\n ", strErrorMessage_.c_str()); int count = 0; for (auto it = client_map.begin(); it!=client_map.end(); ++it) { printf("count==%d ", count); it->second->Dump(); ++count; } printf("\n===ClientPool DUMP END ============\n");}bool ClientPool::Empty() const { return client_map.empty();}/** * 从map当中选取一个连接 * host和port是筛选的端口号 */SocketObjPtr ClientPool::GetConnection(string host, unsigned port) { // get connection operation unique_lock<mutex> lk(resource_mutex); char stringPort[10]; snprintf(stringPort, sizeof(stringPort), "%d", port); string key = host + "###" + stringPort; multimap<string, SocketObjPtr>::iterator sIt = client_map.find(key); if (sIt != client_map.end()) { SocketObjPtr ret = sIt->second; client_map.erase(sIt); return ret; }}/** * 释放特定的连接,就是把SocketObjPtr放回到list当中 * 其实严格地来说这个函数名字不应该叫做释放,而是插入,因为除了插入从池当中取出来的连接之外 * 用户还能插入构造的连接,但是这样做没有意义 */bool ClientPool::ReleaseConnection(SocketObjPtr conn) { unique_lock<mutex> lk(resource_mutex); pair<string, int> peerPair= conn->GetPeer(); char stringPort[10]; snprintf(stringPort, sizeof(stringPort), "%d", peerPair.second); string key = peerPair.first + "###" + stringPort; client_map.insert(make_pair(key, conn)); return true;}/** * 构造函数创建poolsize个连接错误时候用来打印错误信息 */string ClientPool::ErrorMessage() const { return strErrorMessage_; }
0 0
- socket连接池SocketPool分析(七):server连接池与client连接池
- socket连接池SocketPool分析(一):概述
- socket连接池SocketPool分析(十):libevent
- socket连接池SocketPool分析(四):socket连接控制SocketObj
- socket连接池SocketPool分析(六):有意思的socket
- socket连接池SocketPool分析(八):并发服务器
- socket连接池SocketPool分析(九):C10k problem
- socket连接池SocketPool分析(二):《UNPv1》复习(上):socket函数,三次握手,四次挥手
- socket连接池SocketPool分析(三):《UNPv1》复习(下):IO多路复用
- socket连接池SocketPool分析(五):Accept函数,进退维谷的困境
- 七 mysql连接池
- Elasticsearch Java Client连接池
- Java - Socket连接池
- Socket连接池设计
- socket连接池
- java socket连接池
- socket连接池
- socket连接池
- 围圈报数踢三游戏
- 深度分析Java的ClassLoader机制(源码级别)
- IP地址
- Linux常用配置汇总(Centos 7及Debian 8)
- 【LeetCode】8 String to Integer(atoi)
- socket连接池SocketPool分析(七):server连接池与client连接池
- 用浏览器进行代码的简繁转换,解决乱码
- 编译器或者链接器会优化掉虚表吗
- 凸优化中的数学(二)范数,距离,单位球
- 轮询取挂载目录下被更新的文件
- socket连接池SocketPool分析(八):并发服务器
- RaspBerry使用--windows环境下
- 手Q支付(QQ钱包)
- pat 1003. Emergency (25)