Qt中TCP协议通信详解

2022-08-19 18:51:57

TCP协议是经常使用的通信方式。在QT中做了非常友好的封装,使用非常方便。

需要添加的模块:network

Qt中的TCP类:QTcpSocket , QTcpServer

常用函数介绍

连接目标地址和端口

virtual>

    发送数据

    inline qint64 QTcpSocket ::write(const QByteArray &data)

      监听某个地址和端口号

      bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);

        有新的连接信号

        void QTcpServer::newConnection();

          是否有新的连接

          virtual bool QTcpServer::hasPendingConnections() const;

            获取新的连接,必须处理完才能继续接收到连接

            virtual QTcpSocket *QTcpServer::nextPendingConnection();

              收到新的数据信号

              void QTcpSocket::readyRead();

                读取收到的数据,必须读取完才能继续接收

                QByteArray readAll();

                使用案例(example)

                客户端

                #include <QTcpSocket>
                #include <QWidget>
                #include <QLineEdit>
                class Client : public QWidget
                {
                    Q_OBJECT
                public:
                    Client(QWidget *parent);
                
                public slots:
                    void slotSendButtonClick();
                private:
                    QTcpSocket *_socket;
                    QLineEdit *_lineEdit;
                    bool _isConnected;
                };
                #include "client.h"
                #include <QPushButton>
                #include <QHBoxLayout>
                Client::Client(QWidget *parent)
                    : QWidget(parent)
                {
                    _socket = new QTcpSocket(this);
                
                    _lineEdit = new QLineEdit(this);
                    QPushButton *sendButton = new QPushButton("send");
                    connect(sendButton, SIGNAL(clicked()), this, SLOT(slotSendButtonClick()));
                    connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(slotSendButtonClick()));
                    
                    QHBoxLayout *lay = new QHBoxLayout(this);
                    lay->addWidget(_lineEdit);
                    lay->addWidget(sendButton);
                
                    _isConnected = false;
                }
                
                void Client::slotSendButtonClick()
                {
                    if (!_isConnected)
                    {
                        _socket->connectToHost("127.0.0.1", 9988);
                        _isConnected = true;
                    }
                    QString text = _lineEdit->text();
                    if (!text.isEmpty())
                    {
                        _socket->write(text.toUtf8());//发送数据
                        _lineEdit->clear();
                    }
                }

                服务端

                #include <QWidget>
                #include <QTcpServer>
                #include <QTcpSocket>
                class QTextBrowser;
                class Server :public QWidget
                {
                    Q_OBJECT
                public:
                    Server(QWidget *parent);
                public slots:
                    void slotCurrentIndexChanged(const QString&);
                    void slotNewConnection();
                private:
                    QTcpServer *_server;
                    QTcpSocket *_socket;
                    QTextBrowser *_textBrowser;
                };
                #include "server.h"
                #include <QHostAddress>
                #include <QTextBrowser>
                #include <QByteArray>
                #include <QGridLayout>
                #include <QNetworkInterface>
                #include <QComboBox>
                Server::Server(QWidget *parent)
                {
                    _server = new QTcpServer(this);
                    //_server->listen(QHostAddress::Any, 9988);//监听跟本主机相连的所有网口
                    connect(_server, SIGNAL(newConnection()),this, SLOT(slotNewConnection()) );
                
                    QList<QHostAddress> addrList = QNetworkInterface::allAddresses();
                    QComboBox *comboBox = new QComboBox;
                    for (const QHostAddress& addr : addrList)
                    {
                        quint32 ipAddr = addr.toIPv4Address();
                        if (ipAddr != 0)
                        {
                            comboBox->addItem(QHostAddress(ipAddr).toString());
                        }
                    }
                    connect(comboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotCurrentIndexChanged(const QString&)));
                
                
                    _textBrowser = new QTextBrowser(this);
                    QGridLayout *lay = new QGridLayout(this);
                    lay->addWidget(comboBox, 0, 0);
                    lay->addWidget(_textBrowser,1,0);
                }
                
                void Server::slotCurrentIndexChanged(const QString& item)
                {
                    if (!_server->isListening())
                    {
                        _server->listen(QHostAddress(item), 9988);
                    }
                    
                    _textBrowser->append("listen...");
                }
                
                void Server::slotNewConnection()
                {
                    _textBrowser->append("connecting...");
                    while (_server->hasPendingConnections())//必须处理完所有的连接,否则有新连接时就不会在发信号过来
                    {
                        _socket = _server->nextPendingConnection();
                        connect(_socket, &QTcpSocket::readyRead, [&]() {
                            _textBrowser->append("receive message...");
                            QByteArray newMessage = _socket->readAll();
                            _textBrowser->append(QString(newMessage));
                        });
                    }
                }

                使用效果

                以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。