1、功能实现
2、程序简易流程
用一个Map<String,int> 来存放客户端的 socket的ip和客户端的索引(从0开始)。
围绕着这个创建流程。
1、关键点在于如何处理由服务器发出的 new Socket 连接
2、明白socket 通信的关键信号以及流程
3、简单剖析部分代码
重要代码1:处理新到来的 socket
void CServerPool::dealNewSocket(qintptr socketDes)
{//处理新到来的 soketDes
m_numT++;
if(m_numT<=m_maxT){//处理 没有被超出的
int index=0;
if(!m_mapVec.isEmpty()){
index=m_mapVec.begin().key();
m_mapVec.remove(index);
}
else{
index=m_numT-1;
}
if (!m_threadVec.at(index).m_thread->isRunning()) {
m_threadVec.at(index).m_thread->start();
delayMs(600);//延迟600ms 等待线程启动
}
emit m_threadVec.at(index).m_myT->newSocket(index,socketDes);//发送到new socket
}
else{
m_numT=m_maxT;//避免前后的index出错
int index = 0;
if (!m_mapQue.isEmpty()) {
index = m_mapQue.begin().key();
m_mapQue.remove(index);
}
else {
index = m_numQue;
++m_numQue;
}
if (!m_threadQ->isRunning()){
m_threadQ->start();
delayMs(600);//延迟600ms
}
emit m_queueT->newSocket(index,socketDes);
}
}
重要代码2: 线程组 的socket的创建
void MyThread::dealNewSocket(int index,qintptr socketDes)
{
qDebug()<<"当前线程id"<<QThread::currentThreadId();
if (!m_socket) {
m_socket = new MySocket;
if (!m_socket->t0) {
m_socket->t0 = new QTimer;
connect(m_socket->t0, &QTimer::timeout, [=]() {
double nowTime = QDateTime::currentDateTime().toSecsSinceEpoch();
if (nowTime - m_socket->m_frontTime > m_socket->m_outTime) {
QString str = QString("%1 %2已经超时").arg(
m_socket->peerAddress().toString().mid(7)).arg(index);
m_socket->t0->stop();
if (m_socket->isOpen())
m_socket->close();
delayMs(1000);
emit timeOut(m_socket->index, str);
}
});
}
//读取
connect(m_socket, &MySocket::readyRead, [=]() {
m_socket->t0->stop();
QByteArray data = m_socket->readAll();
QString str = m_socket->peerAddress().toString().mid(7);
QString ip=str+QString(" %1").arg(m_socket->index);
emit sendData(ip, data);
m_socket->m_frontTime = QDateTime::currentDateTime().toSecsSinceEpoch();
m_socket->t0->start(1000);
});
//断开连接
connect(m_socket, &QTcpSocket::disconnected, [=]() {
QString str = QString("%1 %2已经断开连接呢").arg(
m_socket->peerAddress().toString().mid(7)).arg(index);
QString ip = m_socket->peerAddress().toString();
emit socketDisConnected(m_socket->index, ip, str);
m_socket->t0->stop();
if(m_socket->isOpen())
m_socket->close();
});
}
m_socket->index = index;
if(m_socket->isOpen())
m_socket->close();
m_socket->setSocketDescriptor(socketDes);//设置socket的标志
QString ip=m_socket->peerAddress().toString();
emit sendAddress(index,ip);
m_socket->m_frontTime = QDateTime::currentDateTime().toSecsSinceEpoch();
m_socket->t0->start(1000);//第一次需要自启
}
重要代码3: 队列线程对socket的创建
void QueueThread::dealNewSocket(int index, qintptr socketDes)
{
MySocket *m_socket = new MySocket;
m_socket->t0 = new QTimer;
m_socket->setSocketDescriptor(socketDes);
m_socket->index = index;
QString ip=m_socket->peerAddress().toString().mid(7)+QString(" %1").arg(index);
m_mapDsocket.insert(ip,m_socket);//添加到指定列表中
//读取
connect(m_socket->t0, &QTimer::timeout, [=]() {
double nowTime = QDateTime::currentDateTime().toSecsSinceEpoch();
if (nowTime - m_socket->m_frontTime > m_socket->m_outTime) {
int lsIndex = m_socket->index;
QString str = QString("%1 %2已经超时").arg(
m_socket->peerAddress().toString().mid(7)).arg(lsIndex);
m_socket->t0->stop();
if (m_socket->isOpen())
m_socket->close();
delayMs(1000);
emit timeOut(str);
}
});
connect(m_socket, &MySocket::readyRead, [=]() {
m_socket->t0->stop();
QByteArray data = m_socket->readAll();
QString ip = m_socket->peerAddress().toString().mid(7)+
QString(" %1").arg(m_socket->index);
emit sendData(ip, data);
m_socket->m_frontTime = QDateTime::currentDateTime().toSecsSinceEpoch();
m_socket->t0->start(1000);
});
//断开连接
connect(m_socket, &QTcpSocket::disconnected, [=]() {
int lsIndex = m_socket->index;
QString ip = m_socket->peerAddress().toString().mid(7)+QString(" %1").arg(lsIndex);
QString str = QString("%1已经断开连接呢").arg(ip);
emit socketDisConnected(lsIndex, ip, str);
m_socket->t0->stop();//关闭定时器
if (m_socket->isOpen()) {
m_socket->close();
delete m_socket;
}
m_mapDsocket.remove(ip);
});
emit sendAddress(index,ip);//返回成功的地址
m_socket->t0->start(1000);
m_socket->m_frontTime = QDateTime::currentDateTime().toSecsSinceEpoch();
}
gitee:https://gitee.com/chenseri/mutiServer
资源地址:https://download.youkuaiyun.com/download/a1ngel/82470844