编程语言
347
通信流程
使用Qt提供的类进行套接字通信比使用标准C API进行网络通信要简单(因为在内部进行了封装) Qt中的套接字通信流程如下:
1. 服务器端
1.1 通信流程
- 创建套接字服务器
QTcpServer
对象 - 通过
QTcpServer
对象设置监听,即:QTcpServer::listen()
- 基于
QTcpServer::newConnection()
信号检测是否有新的客户端连接 - 如果有新的客户端连接调用
QTcpSocket *QTcpServer::nextPendingConnection()
得到通信的套接字对象 - 使用通信的套接字对象
QTcpSocket
和客户端进行通信
1.2 代码片段
服务器端的窗口界面如下图所示:
头文件
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTcpServer> #include <QTcpSocket> #include <QLabel> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_startBtn_clicked(); void on_sendBtn_clicked(); private: Ui::MainWindow *ui; QTcpServer* m_server; QTcpSocket* m_tcp; QLabel* m_status; }; #endif // MAINWINDOW_H
源文件
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle("Tcp - Server"); //创建QServer对象 m_server = new QTcpServer(this); //检测是否有新的客户端连接 connect(m_server,&QTcpServer::newConnection,this,[=](){ m_tcp = m_server->nextPendingConnection(); //连接成功后更新历史记录和底部状态栏 ui->record->append("connect sucessfully"); m_status->setPixmap(QPixmap(":/bingo").scaled(20,20)); //检测客户端是否发送数据 connect(m_tcp,&QTcpSocket::readyRead,this,[=](){ QString recvmsg = m_tcp->readAll(); ui->record->append("client say : " + recvmsg); }); connect(m_tcp,&QTcpSocket::disconnected,this,[=](){ ui->record->append("disconnect..."); m_tcp->close(); m_tcp->deleteLater(); m_status->setPixmap(QPixmap(":/wrong").scaled(20,20)); }); }); m_status = new QLabel; m_status->setPixmap(QPixmap(":/wrong").scaled(20,20)); ui->statusbar->addWidget(new QLabel("connect status : ")); ui->statusbar->addWidget(m_status); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_startBtn_clicked() { unsigned short port = ui->port->text().toInt(); //设置服务器监听 m_server->listen(QHostAddress::Any,port); ui->startBtn->setEnabled(false); } void MainWindow::on_sendBtn_clicked() { QString sendmsg = ui->msg->toPlainText(); m_tcp->write(sendmsg.toUtf8()); ui->record->append("server say : " +sendmsg); ui->msg->clear(); }
2. 客户端
2.1 通信流程
- 创建通信的套接字类
QTcpSocket
对象 - 使用服务器端绑定的IP和端口连接服务器
QAbstractSocket::connectToHost()
- 使用
QTcpSocket
对象和服务器进行通信
2.2 代码片段
客户端的窗口界面如下图所示:
头文件
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTcpSocket> #include <QLabel> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_conBtn_clicked(); void on_disBtn_clicked(); void on_sendBtn_clicked(); private: Ui::MainWindow *ui; QTcpSocket* m_tcp; QLabel* m_status; }; #endif // MAINWINDOW_H
源文件
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle("Tcp - client"); //创建套接字对象 m_tcp = new QTcpSocket(this); //接受服务器的消息 connect(m_tcp,&QTcpSocket::readyRead,this,[=](){ QString recvmsg = m_tcp->readAll(); ui->record->append("server say : " + recvmsg); }); //是否和服务器连接成功 connect(m_tcp,&QTcpSocket::connected,this,[=](){ ui->record->append("connect sucessfully"); m_status->setPixmap(QPixmap(":/bingo").scaled(20,20)); }); //检测是否断开连接 connect(m_tcp,&QTcpSocket::disconnected,this,[=](){ ui->record->append("disconnect......"); ui->disBtn->setEnabled(false); ui->conBtn->setEnabled(true); m_status->setPixmap(QPixmap(":/wrong").scaled(20,20)); }); m_status = new QLabel; m_status->setPixmap(QPixmap(":/wrong").scaled(20,20)); ui->statusbar->addWidget(new QLabel("connect status : ")); ui->statusbar->addWidget(m_status); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_conBtn_clicked() { QString ip = ui->Ip->text(); unsigned short port_tmp = ui->port->text().toInt(); //连接服务器 m_tcp->connectToHost(QHostAddress(ip),port_tmp); ui->conBtn->setEnabled(false); ui->disBtn->setEnabled(true); } void MainWindow::on_disBtn_clicked() { m_tcp->close(); ui->disBtn->setEnabled(false); ui->conBtn->setEnabled(true); } void MainWindow::on_sendBtn_clicked() { QString sendmsg = ui->msg->toPlainText(); m_tcp->write(sendmsg.toUtf8()); ui->record->append("client say : " + sendmsg); ui->msg->clear(); }