qt5之网络通信

QT5 TCP网络通讯

  • 服务器与客户端建立连接listen() - connectToHost();  触发newPendingConnect信号
  • 实时数据通讯write(); read();  触发readyRead信号
  • 通讯主要使用的类:
  • QTcpServer  Class

    QTcpServer类提供了一个基于TCP的服务器。
    这个类可以接受传入的TCP连接。您可以指定端口或让QTcpServer自动选择一个端口。您可以收听特定地址或所有机器的地址。
    调用listen()让服务器侦听传入的连接。每次客户端连接到服务器时,都会发出newConnection()信号。

  • QTcpSocket Class

    QTcpSocket类提供了一个TCP套接字。
    TCP(传输控制协议)是一种可靠的,面向流的,面向连接的传输协议。 它特别适合连续传输数据。
    QTcpSocket是QAbstractSocket的一个方便的子类,它允许你建立一个TCP连接并传输数据流。

  • 建立连接:

    服务器端以监听的方式监听客服端是否有连接请求

    客户端以调用connectToHost()函数主动连接服务器端

  • tcp协议服务器端实现流程

    建立服务器对象

    listen服务器, 通过建立的服务器 监听指定地址/端口的客服端;判断是否有客户连接有连接就触发newConnection();

  • 通过connect处理newConnection()信号;
    server = new QTcpServer(this); //建立一个服务器对象
        server->listen(QHostAddress::Any, 8000);//通过建立的服务器监听指定ip地址及端口号的客服端,如不指定端口号,系统会随机分配
        connect(server, QTcpServer::newConnection,
        [=]()
        {
            qDebug() << "有连接进来";
        }
        );

    tcp协议客户端实现流程

    建立QTcpSocket套节字(ip,端口)

    通过套节字connectToHost()函数主动连接服务器;连接成功则触发服务器QTcpServer::newConnection信号;并发送套节字到服务器端;

    关闭连接;

    QTcpSocket Sc(this);
    Sc.connectToHost("127.0.0.1", 8888);//实际代码中参数要进行类型转化
    Sc.close();

    实时通讯:

    • 客户端到服务器端通讯
    1. 当客户端与服务器端建立连接后;
    2. 客户端与服务器端通讯在客户端通过套节字对象调用write()函数发送上传内容;
    3. 服务器端有客户端数据写入时服务器端会自动调用readyread信号
    4. 服务器端在connect中处理readyread信号,并由nextPendingConnection()函数接收客户端发送的套节字;
    5. 服务器端对接收的套节字进行相应处理,即完成一次客户端到服务器端的通讯
    • 服务器端到客户端的通讯
    1. 当客户端与服务器端建立连接后;
    2. 服务器通过套节字对象调用write()函数发送上传内容;客户端会触发readyread信号
    3. 客户端在connect中处理readyread信号
    客户端到服务器端实现代码:
  • 服务器端头文件widget.h
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QTcpServer>
    #include <QTcpSocket>
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    private slots:
        void on_buttonsend_clicked();
    
    private:
        Ui::Widget *ui;
    
        QTcpServer *server; //建立服务器对象
        QTcpSocket *socket; //套节字对象
        QByteArray tp;   //
    };
    
    #endif // WIDGET_H

    服务器端cpp文件 widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    #include <QDebug>
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
        setWindowTitle("服务器");
        tp = nullptr;
    
        server = new QTcpServer(this);
        server->listen(QHostAddress::Any, 8000);
        connect(server, QTcpServer::newConnection,
                [=]()
        {
            socket = server->nextPendingConnection();
            connect(socket, &QTcpSocket::readyRead, [=]()
            {
                tp = socket->readAll();
                ui->testdis->append(tp);
            });
        }
        );
    
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::on_buttonsend_clicked()
    {
        socket->write(ui->textEdit->toPlainText().toUtf8());
    }

    客户端头文件socket.h:

    #ifndef SOCKET_H
    #define SOCKET_H
    
    #include <QWidget>
    #include <QTcpSocket>
    #include <QHostAddress>
    
    namespace Ui {
    class socket;
    }
    
    class socket : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit socket(QWidget *parent = 0);
        ~socket();
    
    private slots:
    
        void on_buttonLink_clicked();
    
        void on_buttonsend_clicked();
    
        void on_serverclose_clicked();
    
    private:
        Ui::socket *ui;
    
        QTcpSocket *sock;
        QHostAddress adrs;
        quint16 port;
    };
    
    #endif // SOCKET_H

    客户端cpp文件socket.cpp

  • #include "socket.h"
    #include "ui_socket.h"
    
    socket::socket(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::socket)
    {
        ui->setupUi(this);
        sock = new QTcpSocket(this);
        setWindowTitle("张三");
        connect(sock, &QTcpSocket::readyRead,
                [=]()
        {
           ui->textdis->append(sock->readAll());
        });
    }
    
    socket::~socket()
    {
        delete ui;
    }
    
    void socket::on_buttonLink_clicked()
    {
        QString ip = ui->serverIP->text();
        QString p = ui->serverPort->text();
        sock->connectToHost(ip, p.toUShort());
    }
    
    void socket::on_buttonsend_clicked()
    {
        QString temp = ui->textEdit->toPlainText();
        if(!temp.isEmpty())sock->write(temp.toUtf8());
    }
    
    void socket::on_serverclose_clicked()
    {
        sock->close();
    }

    main.cpp文件

    #include "widget.h"
    #include <QApplication>
    #include "socket.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        socket w1;
        w1.show();
    
        return a.exec();
    }

  • 运行的效果如图所示

  • 后续的通信例子还在学习中,本文的参考链接:

  • (1)https://www.cnblogs.com/flowingwind/p/8348519.html

  • (2)https://www.cnblogs.com/findumars/p/5838531.html
  • (3)https://blog.csdn.net/pk124729136/article/details/8087609

猜你喜欢

转载自www.cnblogs.com/tansuoxinweilai/p/10275164.html
今日推荐