日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

Hi,今天用一個小例子,陳述一下 Qt 里使用 TCP 通訊的流程。

代碼鏈接:

https://doc.qt.io/qt-5/examples.NETwork.html

運行效果:

一小例子,了解 TCP 通訊流程 | Qt 示例

 

Server 端

運行效果:

一小例子,了解 TCP 通訊流程 | Qt 示例

 

顯示 IP + 端口,然后靜靜地的等待客戶端的連接。

源碼文件:

msg_server/
├── msg_server.pro
├── main.cpp
├── server.cpp
└── server.h

源碼分析如下。

 

創建 TCP Server

在構造函數中進行初始化:

// server.cpp
Server::Server(QWidget *parent)
    : QDialog(parent)
    , statusLabel(new QLabel)
{
    // 建立 TCP Server,并監聽
    tcpServer = new QTcpServer(this);
    tcpServer->listen()
    
    // 獲取 Server 的 IP 地址,并用其初始化 UI
    [...]

    // 一旦有 TCP 連接,則調用 sendMsg() 發送數據給客戶端
    connect(tcpServer, &QTcpServer::newConnection, this, &Server::sendMsg);
}

要點:

1、QTcpServer 是對 TCP-based server 的封裝。

2、QTcpServer::listen() 用于監聽是否有客戶端發起連接。

3、一旦有客戶端訪問,QTcpServer 會發出 newConnection() 信號,我們通過綁定槽函數 sendMsg() 以實現發送消息的功能。

 

獲取 Server IP

在界面上顯示服務端的 IP 信息:

// server.cpp
Server::Server(QWidget *parent)
    : QDialog(parent)
    , statusLabel(new QLabel)
{
    // 創建 TCP Server
    [...]

    QString ipAddress;

    // 獲得所有的 IP 地址
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();

    // 解析出第一個可用的 IPv4 地址
    for (int i = 0; i < ipAddressesList.size(); ++i) {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
            ipAddressesList.at(i).toIPv4Address()) {
            ipAddress = ipAddressesList.at(i).toString();
            break;
        }
    }

    // 初始化 UI
    [...]
}

要點:

1、QNetworkInterface 是對網絡接口 (例如 lo、eth0...) 的封裝。

2、QNetworkInterface::allAddresses() 會返回系統里所有的 IP 地址。

3、QHostAddress 是對 IP 地址(IPv4、IPv6) 的封裝。

4、QHostAddress::toIPv4Address() 會將點分式的 IPv4 地址轉換為數字式,例如 127.0.0.1 會被轉換為 0x7F000001,失敗則返回 0。

 

給客戶端發送消息

當有客戶端連接到來時,槽函數 sendMsg()會被調用 :

// server.cpp
void Server::sendMsg()
{
    // Prepare message
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out << message[QRandomGenerator::global()->bounded(message.size())];

    // Get pending connection
    QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
    connect(clientConnection, &QAbstractSocket::disconnected,
            clientConnection, &QObject::deleteLater);

    // Send message
    clientConnection->write(block);
    clientConnection->disconnectFromHost();
}

要點:

1、QTcpSocket 是對 TCP Socket 的封裝。

2、為了與主機無關 (字節序等),這里選用 QByteArray 以二進制的格式來存儲數據。使用 QDataStream 可以輕松地將 Message 寫到 QByteArray 里。

3、QDataStream 從各種 IO 設備 (QIODeice 的子類),例如 QByteArray、文件 (QFile) 等讀寫二進制數據。

4、從 QTcpServer::nextPendingConnection() 獲得客戶端的 Socket。

5、用 QTcpSocket::write() 將 Message 通過網絡發給客戶端。

6、最后,通過 QTcpSocket::disconnectFromHost 斷開連接,它會等待直到數據成功被寫出去。

 

Client 端

運行效果:

一小例子,了解 TCP 通訊流程 | Qt 示例

 

每次點擊 "Get Message" 按鈕,客戶端都會從服務端隨機獲取到一條問候信息。

源碼文件:

msg_client/
├── msg_client.pro
├── client.cpp
├── client.h
└── main.cpp

創建 TCP Socket

// client.cpp
Client::Client(QWidget *parent)
    : QDialog(parent)
    , hostCombo(new QComboBox)
    , portLineEdit(new QLineEdit)
    , statusLabel(new QLabel(tr("This examples requires that you run then Message Server example as well.")))
    , getMsgButton(new QPushButton(tr("Get Message")))
    , tcpSocket(new QTcpSocket(this))
{
    // Init UI
    [...]

    // Setup QDataStream's source
    in.setDevice(tcpSocket);
    in.setVersion(QDataStream::Qt_5_10);

    // Setup signal & slot
    connect(getMsgButton, &QAbstractButton::clicked,
            this, &Client::requestNewMsg);
    connect(tcpSocket, &QIODevice::readyRead, this, &Client::readMsg);
}

要點:

1、用 QTcpSocket 創建 TCP Socket。

2、將 QDataStream 數據流的輸入源設置為 Socket。

3、設置信號槽:當 Socket 有數據時,調用 readMsg() 將其讀走。

 

從服務端讀取消息

當用戶點擊 "Get Message" 按鈕時,requestNewMsg() 會被調用

// client.cpp
void Client::requestNewMsg()
{
    getMsgButton->setEnabled(false);
    tcpSocket->abort();
    tcpSocket->connectToHost(hostCombo->currentText(),
                             portLineEdit->text().toInt());
}

要點:

1、QTcpSocket::connectToHost() 向服務端發起連接。

2、該函數沒有返回值,是因為當有錯誤發生時,socket 會發出 error() 信號,我們可以通過綁定對應的槽函數進行錯誤處理。

3、成功連接后,服務端會隨機發送一條信息過來,客戶端接收到消息后,readMsg() 會被調用。

// client.cpp
void Client::readMsg()
{
    QString ;
    in >> nextFortune;
    statusLabel->setText(nextFortune);
    getMsgButton->setEnabled(true);
}

很簡單的流操作,讀到信息后,將其顯示在界面上。

 

總結

用一張圖總結一下 Qt TCP 通訊流程:

一小例子,了解 TCP 通訊流程 | Qt 示例

 

原文鏈接:
https://mp.weixin.qq.com/s/aCyV4HBwzTUZbCrdKsLtBw

文章轉載自:老吳嵌入式

文章來源于:一小例子,了解 TCP 通訊流程 | Qt 示例

原文鏈接:一小例子,了解 TCP 通訊流程 | Qt 示例

版權聲明:本文來源于網絡,免費傳達知識,版權歸原作者所有,如涉及作品版權問題,請聯系我進行刪除

分享到:
標簽:TCP
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定