1. 程式人生 > 其它 >Qt中基於QTcpServer和QTcpSocket的網路通訊

Qt中基於QTcpServer和QTcpSocket的網路通訊

在Qt中,基於Tcp套接字通訊主要用到QTcpServer和QTcpSocket這兩個類:

  • QTcpServer:用於服務端,用來監聽客戶端是否連線。
  • QTcpSocket:套接字類,客戶端與服務端都需要使用,主要是用於操作資料。

一 .QTcpServer常用到的函式

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

        告訴服務端監聽的地址和埠,如果地址是QHostAddress::Any,那麼伺服器將監聽所有網路介面,如果埠為0,就會預設選擇一個埠;

   如果返回為true則為真,否則為假。

       (2).void QTcpServer::newConnection()

         這是一個訊號函式,每次有新的連線時,就會觸發此訊號。

       (3).QTcpSocket *QTcpServer::nextPendingConnection()

          將下一個掛起的連線作為已經連線的QTcpSocket套接字物件返回。

二 .QTcpSocket常用到的函式(QTcpSocket繼承於QAbstractSocket)

         (1).void QAbstractSocket::connected()

          當客戶端與服務端成功建立連線後,便會觸發這個訊號。

          (2).void QIODevice::readyRead()

           每當有新的資料被讀取到,就會觸發這個訊號,比如說伺服器向客戶端傳送資料時,客戶端檢測到有新資料來了,那邊就會觸發此訊號,然後去處理資料。

          (3).void QAbstractSocket::disconnected()

            當客戶端和服務端斷開連線時,就出觸發這個訊號。

          (4).QByteArray QIODevice::readAll()  

           讀取客戶端或服務端傳送過來的資料,並將其作為位元組陣列返回,如果返回一個空的QByteArray那麼就意味著沒有資料讀取或者發生了錯誤。

          (5).qint64 QIODevice::write(const char *data)

           向客戶端或者服務端傳送資料,返回值是實際寫入的位元組數,如果發生了錯誤,那麼返回值為-1;

三.服務端部分程式碼

QTcpServerDemo::QTcpServerDemo(QWidget *parent)
    : QWidget(parent),m_pTcpServer(NULL),m_pTcpSocket(NULL)
{
    ui.setupUi(this);
    
    QString strTitle = (QString(u8"伺服器 埠: %1")).arg(CONNECT_PORT);
    setWindowTitle(strTitle);

    //監聽套接字
    m_pTcpServer = new QTcpServer(this); //指定父物件,讓Qt自動回收記憶體控制元件
    m_pTcpServer->listen(QHostAddress::Any, CONNECT_PORT);

    connect(m_pTcpServer, &QTcpServer::newConnection,
        [=]()
        {
            QString strDisplay;
            //取出建立好連結的套接字
            m_pTcpSocket = m_pTcpServer->nextPendingConnection();
            if (NULL == m_pTcpSocket)
            {
                strDisplay = QString(u8"客戶端連線失敗%3").arg(getCurrentTime());
                ui.m_pTextRead->append(strDisplay);
                return;
            }
            //獲取對方的IP和埠
            QString strIP = m_pTcpSocket->peerAddress().toString();
            quint16 nPort = m_pTcpSocket->peerPort();
            strDisplay = QString(u8"[%1:%2]:連線成功%3").arg(strIP).arg(nPort).arg(getCurrentTime());
            ui.m_pTextRead->append(strDisplay);
            
            connect(m_pTcpSocket, &QTcpSocket::readyRead,
                [=]()
                {
                    //從通訊套接字中取出內容
                    QByteArray array = m_pTcpSocket->readAll();
                    QString str = QString("%1 %2").arg(QString(array)).arg(getCurrentTime());
                    ui.m_pTextRead->append(str);
                }
            );

            connect(m_pTcpSocket, &QTcpSocket::disconnected,
                [=]()
                {
                    QString str =QString(u8"服務端斷開連線......%1").arg(getCurrentTime());
                    ui.m_pTextRead->append(str);
                }
            );
        }
        );

    
}

四.客戶端部分程式碼

QTcpClientDemo::QTcpClientDemo(QWidget *parent)
    : QWidget(parent),m_pTcpSocket(NULL), m_bConnect(false)
{
    ui.setupUi(this);
    
    setWindowTitle(u8"客戶端");

    //分配物件,指定父物件
    m_pTcpSocket = new QTcpSocket(this);
    if (m_pTcpSocket != NULL)
    {
        connect(m_pTcpSocket, &QTcpSocket::connected,
            [=]()
            {
                m_bConnect = true;
                QString str = QString(u8"成功和服務端建立連線......%1").arg(getCurrentTime());
                ui.m_TextRead->append(str);
            }
            );

        connect(m_pTcpSocket, &QTcpSocket::readyRead,
            [=]()
            {
                //獲取對方傳送的內容
                QByteArray array = m_pTcpSocket->readAll();
                QString str = QString("%1 %2").arg(QString(array)).arg(getCurrentTime());
                //新增到編輯區中
                ui.m_TextRead->append(str);
            }
        );

        connect(m_pTcpSocket, &QTcpSocket::disconnected,
            [=]()
            {
                m_bConnect = false;
                QString str = QString(u8"客戶端斷開連線......%1").arg(getCurrentTime());
                ui.m_TextRead->append(str);
            }
        );
    }  
}

五.效果展示

 原始碼地址:https://github.com/coczhang/QTcpDemo