1.Tcp通信核心类
QTcpServer
QTcpSocket
需新增模组 network ,右键项目选中Qt Project Settings
选中Qt Modules ,勾选Network模组点击ok即可
2.服务端代码
#include <QtWidgets/QMainWindow>
#include "ui_QtGuiTcpServer.h"
#include <QListWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QDateTime>
#include <QTcpSocket>
#include <QTcpServer>
#include <QDebug>
#include <QList>
#include <QMap>
#include <QTextEdit>
#include <QListWidgetItem>
#include <QMessageBox>
#include <QThread>
class QtGuiTcpServer : public QMainWindow
{
Q_OBJECT
public:
QtGuiTcpServer(QWidget *parent = Q_NULLPTR);
~QtGuiTcpServer();
void AddLog(QString mStr);
private:
Ui::QtGuiTcpServerClass ui;
QTcpServer *m_TcpServer = NULL;//服务端
QMap<QString,QTcpSocket *> m_Sockets;//负责存储服务端与客户端通信的套接字集合
private slots:
void btn_Open_Clicked();
void ListenConnectRequst();//服务端监听
void TcpServerReadData();//服务端读数据
void TcpClientDisconnected();//客户端断开
void TcpServerSendData();//服务端发送数据
void TcpServerSendAll();//服务端广播
void ClearLog();
};
#include "QtGuiTcpServer.h"
QtGuiTcpServer::QtGuiTcpServer(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.btn_open, &QPushButton::clicked, this, &QtGuiTcpServer::btn_Open_Clicked);
connect(ui.pushButton, &QPushButton::clicked, this, &QtGuiTcpServer::TcpServerSendData);
connect(ui.pushButton_2, &QPushButton::clicked, this, &QtGuiTcpServer::TcpServerSendAll);
connect(ui.pushButton_3, &QPushButton::clicked, this, &QtGuiTcpServer::ClearLog);
}
QtGuiTcpServer::~QtGuiTcpServer(void)
{
for (int i = 0; i < m_Sockets.count(); i++)//断开任何信号与任何槽的关联
{
m_Sockets.values()[i]->disconnectFromHost();//掐断所有客户端连接
i--;
}
}
//开启服务端
void QtGuiTcpServer::btn_Open_Clicked(void)
{
QString btnName = ui.btn_open->text();
if (btnName == "打开")
{
if (m_TcpServer == NULL)
{
m_TcpServer = new QTcpServer(this);
}
ui.btn_open->setText("关闭");
m_TcpServer->listen(QHostAddress::Any, ui.ledit_port->text().toUInt());//监听ipv4或ipv6地址
connect(m_TcpServer, SIGNAL(newConnection()), this, SLOT(ListenConnectRequst()));//监听
}
else
{
ui.btn_open->setText("打开");
disconnect(m_TcpServer, nullptr, this, nullptr);//断开任何信号与任何槽的关联---槽函数绑定的次数为调用的次数
for (int i = 0; i < m_Sockets.count(); i++)//断开任何信号与任何槽的关联
{
m_Sockets.values()[i]->disconnectFromHost();//掐断所有客户端连接
i--;
}
m_TcpServer->close();//释放服务端
AddLog("服务端已关闭!");
}
}
//服务端发送数据
void QtGuiTcpServer::TcpServerSendData(void)
{
QList<QListWidgetItem *> mItems = ui.listWidget_2->selectedItems();
if (mItems.isEmpty())
{
QMessageBox::warning(this,"警告","请选中一行");
return;
}
QString mSocketKey = mItems[0]->text();
QTcpSocket *mSocket = m_Sockets.value(mSocketKey);
QString mSendData = ui.textEdit->toPlainText();
QByteArray mData = mSendData.toUtf8();
mSocket->write(mData);
}
//服务端广播
void QtGuiTcpServer::TcpServerSendAll(void)
{
for (int i=0;i<ui.listWidget_2->count();i++)
{
QString mSocketKey = ui.listWidget_2->item(i)->text();
QTcpSocket *mSocket = m_Sockets.value(mSocketKey);
QString mSendData = ui.textEdit->toPlainText();
QByteArray mData = mSendData.toUtf8();
mSocket->write(mData);
}
}
//监听连接请求---槽函数--信号QTcpServer::newConnection
void QtGuiTcpServer::ListenConnectRequst(void)
{
QTcpSocket *mSocket = m_TcpServer->nextPendingConnection();
QString mSocketKey = mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort());
AddLog(mSocketKey + "连接成功");
if (!m_Sockets.contains(mSocketKey))
{
m_Sockets.insert(mSocketKey,mSocket);//将新客户端添加入集合
ui.listWidget_2->addItem(mSocketKey);
connect(mSocket, &QTcpSocket::readyRead, this, &QtGuiTcpServer::TcpServerReadData);//读取数据信号与槽
connect(mSocket, &QTcpSocket::disconnected, this, &QtGuiTcpServer::TcpClientDisconnected);//客户端断开时信号与槽
}
}
//读取数据
void QtGuiTcpServer::TcpServerReadData(void)
{
QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
QByteArray mData = mSocket->readAll();
AddLog(mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort()) + " = " + mData);//显示读取到的信息
}
//客户端断开
void QtGuiTcpServer::TcpClientDisconnected(void)
{
QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
QString mSocketKey = mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort());
AddLog(mSocketKey + "断开连接");//显示读取到的信息
disconnect(mSocket, nullptr, this, nullptr);//断开任何信号与任何槽的关联
m_Sockets.remove(mSocketKey);//将之从集合中删除
for (int i=0;i<ui.listWidget_2->count();i++)
{
QString mStr = ui.listWidget_2->item(i)->text();
if (mStr == mSocketKey)
{
ui.listWidget_2->takeItem(i);
break;
}
}
mSocket->close();
}
//添加日志
void QtGuiTcpServer::AddLog(QString mStr)
{
if (ui.listWidget->count() > 100)
{
ui.listWidget->takeItem(98);//删除98行
}
ui.listWidget->insertItem(0, QDateTime::currentDateTime()
.toString("HH:mm:ss zzz") + " -> " + mStr);
}
void QtGuiTcpServer::ClearLog(void)
{
ui.listWidget->clear();
}
3.客户端代码
#include <QtWidgets/QMainWindow>
#include "ui_QtGuiTcpClient.h"
#include <QPushButton>
#include <QTcpSocket>
#include <QNetworkInterface>
#include <QDateTime>
#include <QThread>
class QtGuiTcpClient : public QMainWindow
{
Q_OBJECT
public:
QtGuiTcpClient(QWidget *parent = Q_NULLPTR);
private:
Ui::QtGuiTcpClientClass ui;
QTcpSocket *m_Socket;
void AddLog(QString mStr);//添加日志
private slots:
void GetHostIPAdress();//获取本地ip地址
void TcpClientConnectServer();//连接服务端
void TcpClientDisconnServer();//断开服务端
void TcpClientReadData();//接收数据
void TcpClientSendData();//发送数据
void ClearText();//清空日志
};
#include "QtGuiTcpClient.h"
QtGuiTcpClient::QtGuiTcpClient(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.pushButton, &QPushButton::clicked, this, &QtGuiTcpClient::GetHostIPAdress);
connect(ui.pushButton_2, &QPushButton::clicked, this, &QtGuiTcpClient::TcpClientConnectServer);
connect(ui.pushButton_3, &QPushButton::clicked, this, &QtGuiTcpClient::TcpClientSendData);
connect(ui.pushButton_4, &QPushButton::clicked, this, &QtGuiTcpClient::ClearText);
}
//获取本地ip地址
void QtGuiTcpClient::GetHostIPAdress(void)
{
QString mIpAddress;
QList<QHostAddress> mIpAddressesList = QNetworkInterface::allAddresses();
for (int i = 0; i < mIpAddressesList.size(); ++i)
{
if (mIpAddressesList.at(i) != QHostAddress::LocalHost && mIpAddressesList.at(i).toIPv4Address())
{
mIpAddress = mIpAddressesList.at(i).toString();
}
}
if (mIpAddress.isEmpty())
{
mIpAddress = QHostAddress(QHostAddress::LocalHost).toString();
}
ui.lineEdit_2->setText(mIpAddress);
}
//连接服务端
void QtGuiTcpClient::TcpClientConnectServer(void)
{
QString mStr = ui.pushButton_2->text();
if (mStr == "连接")
{
m_Socket = new QTcpSocket;
ui.pushButton_2->setText("断开");
//获取服务器ip和端口
QString mIp = ui.lineEdit_2->text();
qint16 mPort = ui.lineEdit->text().toUInt();
//主动和服务器建立连接
m_Socket->connectToHost(QHostAddress(mIp), mPort);
connect(m_Socket, &QTcpSocket::readyRead, this, &QtGuiTcpClient::TcpClientReadData);//读取数据信号与槽
connect(m_Socket, &QTcpSocket::disconnected, this, &QtGuiTcpClient::TcpClientDisconnServer);//客户端断开时信号与槽
AddLog("连接成功!");
}
else
{
m_Socket->disconnectFromHost();
m_Socket->close();
ui.pushButton_2->setText("连接");
}
}
//断开服务端
void QtGuiTcpClient::TcpClientDisconnServer(void)
{
QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
QString mSocketKey = mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort());
AddLog(mSocketKey + "断开连接");//显示读取到的信息
disconnect(mSocket, nullptr, this, nullptr);//断开任何信号与任何槽的关联
mSocket->close();
ui.pushButton_2->setText("连接");
}
//接收数据
void QtGuiTcpClient::TcpClientReadData(void)
{
QTcpSocket *mSocket = qobject_cast<QTcpSocket *>(sender());//获取信号发起者
QByteArray mData = mSocket->readAll();
AddLog(mSocket->peerAddress().toString() + ":" + QString::number(mSocket->peerPort()) + " = " + mData);//显示读取到的信息
}
//添加日志
void QtGuiTcpClient::AddLog(QString mStr)
{
if (ui.listWidget->count() > 100)
{
ui.listWidget->takeItem(98);//删除98行
}
ui.listWidget->insertItem(0, QDateTime::currentDateTime()
.toString("HH:mm:ss zzz") + " -> " + mStr);
}
//服务端发送数据
void QtGuiTcpClient::TcpClientSendData(void)
{
QString mSendData = ui.lineEdit_3->text();
QByteArray mData = mSendData.toUtf8();
m_Socket->write(mData);
}
//清除日志
void QtGuiTcpClient::ClearText(void)
{
ui.listWidget->clear();
}