Qt网络通信服务端与客户端学习
一、项目概述
本项目基于Qt框架实现了TCP服务端与客户端的基本通信,涵盖连接、消息收发、断开管理等功能,适合初学者系统学习Qt网络模块的实际用法。
二、项目结构
- 52/ 服务端:main.cpp、widget.cpp、widget.h
- 53/ 客户端:main.cpp、widget.cpp、widget.h
三、环境配置
- Qt 5.x及以上
- 启用network、widgets模块
- C++11支持
四、服务端核心代码详解(52目录)
1. main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
2. widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui; // UI指针
QTcpServer *tcpServer; // TCP服务端对象
private slots:
void mNewConnetion(); // 新连接处理槽
void receiveMessages(); // 接收消息槽
void mStateChanged(QAbstractSocket::SocketState); // 连接状态变化槽
void on_pushButton_3_clicked(); // 发送消息按钮槽
void on_pushButton_clicked(); // 开始监听按钮槽
void on_pushButton_2_clicked(); // 停止监听按钮槽
};
#endif // WIDGET_H
3. widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
tcpServer = new QTcpServer(this);
this->setWindowTitle("服务端");
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(mNewConnetion()));
ui->pushButton_2->setEnabled(false);
}
Widget::~Widget()
{
delete ui;
}
void Widget::mNewConnetion()
{
QTcpSocket *tmpTcpSocket = tcpServer->nextPendingConnection();
QString ipaddr = tmpTcpSocket->peerAddress().toString();
quint16 port = tmpTcpSocket->peerPort();
ui->textBrowser->append("服务端:客户端的ip地址:" + ipaddr);
ui->textBrowser->append("服务端:客户端的端口:" + QString::number(port));
connect(tmpTcpSocket, SIGNAL(readyRead()), this, SLOT(receiveMessages()));
connect(tmpTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this, SLOT(mStateChanged(QAbstractSocket::SocketState)));
}
void Widget::receiveMessages()
{
QTcpSocket *tmpTcpSocket = (QTcpSocket *)sender();
ui->textBrowser->append("客户端:" + tmpTcpSocket->readAll());
}
void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
QTcpSocket *tmpTcpSocket = (QTcpSocket *)sender();
switch (state) {
case QAbstractSocket::UnconnectedState:
ui->textBrowser->append("服务端:客户端断开连接");
tmpTcpSocket->deleteLater();
break;
case QAbstractSocket::ConnectedState:
ui->textBrowser->append("服务端:客户端已连接");
break;
default:
break;
}
}
void Widget::on_pushButton_3_clicked()
{
QList <QTcpSocket *> socketList = tcpServer->findChildren<QTcpSocket *>();
qDebug() << "tcpSocket 数量:" << socketList.count() << endl;
if (socketList.count() == 0) {
ui->textBrowser->append("当前没有客户端连接,请先与客户端连接!");
return;
}
foreach (QTcpSocket *tmpTcpSocket, socketList) {
tmpTcpSocket->write(ui->lineEdit->text().toUtf8());
}
ui->textBrowser->append("服务端:" + ui->lineEdit->text());
}
void Widget::on_pushButton_clicked()
{
tcpServer->listen(QHostAddress("192.168.1.59"), 9999);
ui->textBrowser->append("服务端:监听的ip地址和端口:192.168.1.59,9999");
ui->pushButton_2->setEnabled(true);
ui->pushButton->setEnabled(false);
}
void Widget::on_pushButton_2_clicked()
{
tcpServer->close();
ui->pushButton->setEnabled(true);
ui->pushButton_2->setEnabled(false);
}
五、客户端核心代码详解(53目录)
1. main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
2. widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QHostAddress>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui; // UI指针
QTcpSocket *tcpSocket; // TCP客户端对象
private slots:
void receiveMessages(); // 接收消息槽
void mStateChanged(QAbstractSocket::SocketState); // 连接状态变化槽
void on_pushButton_3_clicked(); // 发送消息按钮槽
void on_pushButton_clicked(); // 连接服务端按钮槽
void on_pushButton_2_clicked(); // 断开连接按钮槽
};
#endif // WIDGET_H
3. widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("客户端");
ui->pushButton_2->setEnabled(false);
tcpSocket = new QTcpSocket(this);
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveMessages()));
connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(mStateChanged(QAbstractSocket::SocketState)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::receiveMessages()
{
ui->textBrowser->append("服务端:" + tcpSocket->readAll());
}
void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
switch (state) {
case QAbstractSocket::UnconnectedState:
ui->textBrowser->append("客户端:与服务端断开连接");
ui->pushButton->setEnabled(true);
ui->pushButton_2->setEnabled(false);
break;
case QAbstractSocket::ConnectedState:
ui->textBrowser->append("客户端:已连接服务端");
ui->pushButton->setEnabled(false);
ui->pushButton_2->setEnabled(true);
break;
default:
break;
}
}
void Widget::on_pushButton_3_clicked()
{
if (tcpSocket->state() == QAbstractSocket::ConnectedState) {
tcpSocket->write(ui->lineEdit->text().toUtf8());
ui->textBrowser->append("客户端:" + ui->lineEdit->text());
} else
ui->textBrowser->append("请先与服务端连接!");
}
void Widget::on_pushButton_clicked()
{
ui->textBrowser->append("客户端:监听的ip地址和端口:192.168.1.59,9999");
tcpSocket->connectToHost(QHostAddress("192.168.1.59"), 9999);
}
void Widget::on_pushButton_2_clicked()
{
tcpSocket->disconnectFromHost();
}
757

被折叠的 条评论
为什么被折叠?



