


这里只提供了服务端实现并发的核心源代码,主要有三个文件:
三者之间可以自己定义信号槽实现通信,整体源代码不提供,请谅解。
networkdebugtools.h
#ifndef NETWORKDEBUGTOOLS_H
#define NETWORKDEBUGTOOLS_H
#include
#include
#include
#include
#include "tcpservertools.h"
#include
QT_BEGIN_NAMESPACE
namespace Ui { class NetworkDebugTools; }
QT_END_NAMESPACE
class NetworkDebugTools : public QWidget
{
Q_OBJECT
public:
NetworkDebugTools(QWidget *parent = nullptr);
~NetworkDebugTools();
private slots:
void on_pushButton_send_clicked();
void on_pushButton_listen_clicked();
private:
Ui::NetworkDebugTools *ui;
TcpServerTools *mTcpServerTools;
};
#endif // NETWORKDEBUGTOOLS_H
networkdebugtools.cpp
#include "networkdebugtools.h"
#include "ui_networkdebugtools.h"
#include
#include
#include
NetworkDebugTools::NetworkDebugTools(QWidget *parent)
: QWidget(parent)
, ui(new Ui::NetworkDebugTools)
{
ui->setupUi(this);
mTcpServerTools = new TcpServerTools();
}
void NetworkDebugTools::on_pushButton_send_clicked()
{
//获取当前选中的客户端信息
QString curAddr = ui->tableWidget_clientInfo->item(curRow, 0)->text();
QHash<int, TcpSocketTools*>::iterator iter = mTcpServerTools->tcpClient->begin();
for (; iter != mTcpServerTools->tcpClient->end(); iter++) {
QString iterAddr = iter.value()->peerAddress().toString() + ":" + QString::number(iter.value()->peerPort());
if (iterAddr.compare(curAddr) == 0) {
//这里hash容器tcpClient中保存的value就是socket,可以直接通过socket给客户端发送数据
//同样可以通过该socket获取客户端的ip和端口,然后与我们点击的客户端信息比对,就可以实现对指定客户端发送消息
iter.value()->write(ui->plainTextEdit_send->toPlainText().toLocal8Bit());
break;
}
}
}
void NetworkDebugTools::on_pushButton_listen_clicked()
{
if (ui->pushButton_listen->text().compare("监听") == 0) {
ui->pushButton_listen->setText("关闭");
mTcpServerTools->setMaxPendingConnections(mConfigTools->getConnCount());
mTcpServerTools->startListen();
}
else {
ui->pushButton_listen->setText("监听");
mTcpServerTools->closeConnect();
}
}
tcpservertools.h
#ifndef TCPSERVERTOOLS_H
#define TCPSERVERTOOLS_H
#include
#include
#include
#include
#include
#include "tcpsockettools.h"
#define THREAD_MAX 20
class TcpServerTools : public QTcpServer
{
Q_OBJECT
public:
explicit TcpServerTools(QTcpServer *parent = 0);
~TcpServerTools();
//开始监听
bool startListen();
//关闭连接
void closeConnect();
//设置最大连接数
void setMaxPendingConnections(int numConnections);
protected:
// 有新连接到来时,该函数会被触发
void incomingConnection(qintptr socketDescriptor);
private:
QTcpServer *mTcpServer; //tcp服务对象
public:
QHash<int, TcpSocketTools*> *tcpClient;// 该对象中保存套接字
};
#endif // TCPSERVERTOOLS_H
tcpservertools.cpp
#include "tcpservertools.h"
TcpServerTools::TcpServerTools(QTcpServer *parent) : QTcpServer(parent)
{
tcpClient = new QHash<int, TcpSocketTools*>;
}
TcpServerTools::~TcpServerTools()
{
}
bool TcpServerTools::startListen() {
//监听连接
this->listen(QHostAddress(mIp), mPort.toInt());
return true;
}
void TcpServerTools::closeConnect(){
// 断开连接时,删除tcpClient中保存的套接字,并清除 tcpClient
QHash<int, TcpSocketTools*>::const_iterator iterC = tcpClient->constBegin();
for (; iterC != tcpClient->constEnd(); iterC++){
iterC.value()->deleteLater();
}
tcpClient->clear();
this->close();
}
void TcpServerTools::incomingConnection(qintptr socketDescriptor) {
//创建 TcpSocketTools 对象
TcpSocketTools *socketTools = new TcpSocketTools(socketDescriptor);
QString connAddr = socketTools->peerAddress().toString() + ":" + QString::number(socketTools->peerPort());
// 有新连接时,保存socket到 QHash 类型的tcpClient指针对象中
tcpClient->insert(socketDescriptor, socketTools);
}
// 设置最大连接数
void TcpServerTools::setMaxPendingConnections(int numConnections) {
QTcpServer::setMaxPendingConnections(numConnections);
}
tcpsockettools.h
#ifndef TCPSOCKETTOOLS_H
#define TCPSOCKETTOOLS_H
#include
class TcpSocketTools : public QTcpSocket
{
Q_OBJECT
public:
explicit TcpSocketTools(qintptr socketDescriptor, QTcpSocket *parent = 0);
~TcpSocketTools();
public slots :
void onReadyRead();
void onDisconnected();
private:
qintptr socketID;
};
#endif // TCPSOCKETTOOLS_H
tcpsockettools.cpp
#include "tcpsockettools.h"
#include
TcpSocketTools::TcpSocketTools(qintptr socketDescriptor, QTcpSocket *parent) : QTcpSocket(parent),socketID(socketDescriptor)
{
this->setSocketDescriptor(socketDescriptor);
connect(this, &TcpSocketTools::readyRead, this, &TcpSocketTools::onReadyRead);
connect(this, &TcpSocketTools::disconnected, this, &TcpSocketTools::onDisconnected);
}
TcpSocketTools::~TcpSocketTools()
{
}
void TcpSocketTools::onReadyRead() {
//处理接受到的数据
}
void TcpSocketTools::onDisconnected() {
//处理断开连接请求
}