本文主要记录学习QT网络通信,在本项目中主要作为通信中的客户端
概述
QT是一个跨平台的C++图形用户界面应用程序框架,支持多平台开发
创建时能够使用的基类有三种,QMainWindow、QWidget、QDialog,分别对应带菜单栏的窗口、空白窗口以及对话框窗口
注意VS中要添加相应模块才能使用相应头文件,比如套接字相关类在network模块中
网络通信流程
TCP:
UDP:
信号与槽
当某对象触发某个事件后,发出一个信号,使用连接(connect)函数,绑定另一个对象的一个函数(槽)来做相应的处理
信号与槽都可以自定义
TCP通信代码实现
QTcpServer:服务器类
QTcpSocket:套接字类
服务器端代码:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::WidgetClass *ui;
QTcpServer* serv;//服务器类
QTcpSocket* conntcp;//套接字类
public slots:
void setListen_clicked();
void sendMessage_clicked();
};
#include "widget.h"
//可以解决乱码问题
#ifdef _MSC_VER
#pragma execution_character_set("utf-8")
#endif
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::WidgetClass())
{
ui->setupUi(this);
ui->port->setText("8899");
setWindowTitle("服务器");
ui->status->setText("未连接");
serv = new QTcpServer(this);
//有连接到来接受连接
connect(serv, &QTcpServer::newConnection, this, [=]()
{
conntcp = serv->nextPendingConnection();
ui->status->setText("已连接");
//有读事件,读数据,槽函数可以是lambda表达式
connect(conntcp, &QTcpSocket::readyRead, this, [=]()
{
QByteArray data = conntcp->readAll();
ui->record->append("客户端say:" + data);
}
);
//客户端关闭连接时释放套接字对象
connect(conntcp, &QTcpSocket::disconnected, this, [=]()
{
conntcp->close();
ui->status->setText("未连接");
conntcp->deleteLater();
});
}
);
//点击启动监听按钮,开始监听连接
connect(ui->setListen, &QPushButton::clicked, this, &Widget::setListen_clicked);
//点击按钮发送信息
connect(ui->sendMessage, &QPushButton::clicked, this, &Widget::sendMessage_clicked);
}
Widget::~Widget()
{
delete ui;
}
void Widget::setListen_clicked() {
unsigned short port = ui->port->text().toUShort();
serv->listen(QHostAddress::Any, port);
ui->setListen->setDisabled(true);
}
void Widget::sendMessage_clicked() {
QString msg = ui->message->toPlainText();
conntcp->write(msg.toUtf8());
ui->record->append("服务器say:" + msg);
}
界面:
客户端代码:
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::WidgetClass *ui;
QTcpSocket* conntcp;
public slots:
void connect_clicked();
void sendMessage_clicked();
void disconnect_clicked();
};
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::WidgetClass())
{
ui->setupUi(this);
ui->port->setText("8899");
ui->ip->setText("127.0.0.1");
setWindowTitle("客户端");
ui->status->setText("未连接");
ui->disconnect->setDisabled(true);
conntcp = new QTcpSocket(this);
//读事件
connect(conntcp, &QTcpSocket::readyRead, this, [=]()
{
QByteArray data = conntcp->readAll();
ui->record->append("服务器say:" + data);
}
);
//连接断开
connect(conntcp, &QTcpSocket::disconnected, this, [=]()
{
ui->status->setText("未连接");
ui->record->append("客户端已经断开服务器连接...");
ui->disconnect->setDisabled(true);
ui->connect->setDisabled(false);
});
//已连接
connect(conntcp, &QTcpSocket::connected, this, [=]() {
ui->disconnect->setDisabled(false);
ui->connect->setDisabled(true);
ui->status->setText("已连接");
ui->record->append("已经成功连接到了服务器...");
});
connect(ui->connect, &QPushButton::clicked, this, &Widget::connect_clicked);
connect(ui->disconnect, &QPushButton::clicked, this, &Widget::disconnect_clicked);
connect(ui->sendMessage, &QPushButton::clicked, this, &Widget::sendMessage_clicked);
}
Widget::~Widget()
{
delete ui;
}
void Widget::connect_clicked() {
QString ip = ui->ip->text();
unsigned short port = ui->port->text().toUShort();
conntcp->connectToHost(QHostAddress(ip), port);
}
void Widget::sendMessage_clicked() {
QString msg = ui->message->toPlainText();
conntcp->write(msg.toUtf8());
ui->record->append("客户端say:" + msg);
}
void Widget::disconnect_clicked() {
conntcp->close();//触发QTcpSocket::disconnected
}
界面:
结果:
参考:
Qt多线程网络通信–b站,爱编程的大丙