连接
一 连接池 SocketPool
1 介绍
- 一般情况客户端只有一个连接和服务器通信
- 客户端同时有多个连接和服务器通信
- 第一个链接: 数据交换
- 第2-6个连接: 下载
- 提交效率的点:
- 建立连接的时候:connect
2 处理思路: 套接字连接池
- 在进行业务通信之前, 先把需要的连接创建出来, 存储到一个容器中
- 当前要通信的时候, 从容器中取出一个连接 (fd) -> 和服务器通信
- 通信完成之后 -> 将这个连接放回到容器中
二 c++实现简单的socket连接池
#include "TcpSocket.h"
#include <pthread.h>
#include <queue>
// 套接字连接池
class SocketPool
{
public:
SocketPool(string ip, unsigned short port, int capacity);
// 从连接池中获取一条连接
TcpSocket* getConnect();
// 将连接放回到连接池中
void putConnect(TcpSocket* tcp, bool isValid = true);
// 判断连接池是否为空
inline bool isEmpty();
~SocketPool();
private:
void createConnect();
private:
string m_ip; // 服务器IP
int m_capacity; // 连接池最大容量
int m_nodeNumber;
unsigned short m_port; // 服务器端口
queue<TcpSocket*> m_list; // 存储连接的队列
pthread_mutex_t m_mutex;
};
(1)初始化
SocketPool::SocketPool(string ip, unsigned short port, int capacity) :
m_capacity(capacity),
m_nodeNumber(capacity),
m_ip(ip),
m_port(port)
{
pthread_mutex_init(&m_mutex, NULL);
// 创建连接池中需要的连接
createConnect();
}
(2)创建连接
void SocketPool::createConnect()
{
cout << " == current list size: " << m_list.size() << endl;
cout << "=== 容量: " << m_nodeNumber << endl;
if (m_list.size() >= m_nodeNumber)
{
return;
}
// 创建socket通信对象
TcpSocket* tcp = new TcpSocket;
// 连接服务器
int ret = tcp->connectToHost(m_ip, m_port);
if (ret == 0)
{
m_list.push(tcp);
cout << "create new +++++ connect size: " << m_list.size() << endl;
}
else
{
delete tcp;
}
// 递归创建连接
createConnect();
}
(3)放回连接
void SocketPool::putConnect(TcpSocket * tcp, bool isValid)
{
pthread_mutex_lock(&m_mutex);
// 判断连接是否可用
if (isValid)
{
// 放回连接池中
m_list.push(tcp);
cout << "放回的连接可用√√√√√√√√" << m_list.size() << endl;
}
else
{
cout << "连接不可用XXXXXXXX" << m_list.size() << endl;
// 关闭坏掉的连接, 并释放对象
tcp->disConnect();
delete tcp;
// 创建新的连接
m_nodeNumber = m_list.size() + 1;
createConnect();
}
cout << "connect size: " << m_list.size() << endl;
pthread_mutex_unlock(&m_mutex);
}
(4)获取连接
TcpSocket * SocketPool::getConnect()
{
if (m_list.empty())
{
return NULL;
}
pthread_mutex_lock(&m_mutex);
// 取出队头连接
TcpSocket* socket = m_list.front();
// 弹出取出的连接
m_list.pop();
cout << "connect size: " << m_list.size() << endl;
pthread_mutex_unlock(&m_mutex);
return socket;
}