Qt之 TCP/IP Socket通信


參考文章:qt socket通信

Socket通信

Qt中提供的所有的Socket類都是非阻塞的。

Qt中常用的用於socket通信的套接字類:

  • QTcpServer

    用於TCP/IP通信, 作為服務器端套接字使用

  • QTcpSocket

    用於TCP/IP通信,作為客戶端套接字使用。

  • QUdpSocket

    用於UDP通信,服務器,客戶端均使用此套接字。

 TCP/IP

在Qt中實現TCP/IP服務器端通信的流程:

  • 創建套接字
  • 將套接字設置為監聽模式
  • 等待並接受客戶端請求

    可以通過QTcpServer提供的void  newConnection()信號來檢測是否有連接請求,如果有可以在對應的槽函數中調用nextPendingConnection函數獲取到客戶端的Socket信息(返回值為QTcpSocket*類型指針),通過此套接字與客戶端之間進行通信。

  • 接收或者向客戶端發送數據

    接收數據:使用read()或者readAll()函數

    發送數據:使用write()函數

客戶端通信流程:

  • 創建套接字

  • 連接服務器

    可以使用QTcpSocket類的connectToHost()函數來連接服務器。

  • 向服務器發送或者接受數據

              

關於“套接字

server端:

#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H

#include <QWidget>
#include <QTcpServer> //監聽套接字
#include <QTcpSocket> //通信套接字

namespace Ui {
class serverWidget;
}

class serverWidget : public QWidget
{
    Q_OBJECT

public:
    explicit serverWidget(QWidget *parent = 0);
    ~serverWidget();

private slots:
    void on_buttonSend_clicked();

    void on_buttonClose_clicked();

private:
    Ui::serverWidget *ui;
    QTcpServer *tcpServer; //監聽套接字
    QTcpSocket *tcpSocket; //通信套接字
};

#endif // SERVERWIDGET_H
#include "serverwidget.h"
#include "ui_serverwidget.h"

#pragma execution_character_set("utf-8")

serverWidget::serverWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::serverWidget)
{
    ui->setupUi(this);
    tcpServer = NULL;
    tcpSocket = NULL;
    //監聽套接字,指定父對象,讓其自動回收空間
    tcpServer = new QTcpServer(this);
    //1.QTcpServer對象負責監聽是否有客戶端連接此服務器。它是通過這樣一個函數監聽的
    //第一個參數表示服務器監聽的地址,如果后面是Any表示監聽本機的所有網口的,第二個參數表示監聽的網絡端口
    tcpServer->listen(QHostAddress::Any, 8888);
    setWindowTitle("Sever");
    //2.如果服務器監聽到有客戶端和它進行連接,服務器就會觸發newConnection這個信號。同時客戶端一旦和服務器連接成功,
    //客戶端會觸發connected這個信號,表示已經成功和服務器連接。
    connect(tcpServer, &QTcpServer::newConnection,
            [=]()
            {
                //3.當服務器和客戶端建立好連接之后,服務器需要返回一個QTcpSocket對象來和客戶端進行通信,通常通過這個函數來返回一個建立好連接的套接字。
                //客戶端和服務器各有一個通信套接字,可以看出,每一方的套接字都可以獲得對方的相關信息
                //接着就可以通過兩個的通信套接字來完成通信。
                //取出建立好連接的套接字
                tcpSocket = tcpServer->nextPendingConnection();
                //獲取對方的IP和端口
                QString ip = tcpSocket->peerAddress().toString();
                qint16 port = tcpSocket->peerPort();
                QString temp = QString("[%1:%2]:成功連接").arg(ip).arg(port);

                ui->textEditRead->setText(temp);
                //4.當一端發送成功之后,"接收方"會觸發這么一個信號,readyRead,這樣我們就能夠讀取套接字當中的內容了。
                connect(tcpSocket, &QTcpSocket::readyRead,
                        [=]()
                        {
                            //從通信套接字中取出內容
                           QByteArray array = tcpSocket->readAll();
                           ui->textEditRead->append(array);
                        }
               );
             }
             );
}

serverWidget::~serverWidget()
{
    delete ui;
}

void serverWidget::on_buttonSend_clicked()
{
     if(NULL == tcpSocket)
     {
         return;
     }
     //獲取編輯區內容
     QString str = ui->textEditWrite->toPlainText();
     //給對方發送數據, 使用套接字是tcpSocket
     tcpSocket->write(str.toUtf8().data() );
}

void serverWidget::on_buttonClose_clicked()
{
    if(NULL == tcpSocket)
     {
         return;
     }
     //主動和客戶端端口連接
     tcpSocket->disconnectFromHost();
     tcpSocket->close();
     tcpSocket = NULL;
}

客戶端:

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>//通信套接字

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_buttonConnect_clicked();

    void on_buttonSend_clicked();

    void on_buttonClose_clicked();

private:
    Ui::Widget *ui;
    QTcpSocket *tcpsocket;

};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#pragma execution_character_set("utf-8")

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpsocket = NULL;

    //0.分配空間,指定父對象
    tcpsocket = new QTcpSocket(this);

    setWindowTitle("客戶端");
    //3.連接成功之后客戶端會觸發這樣一個信號 connected
    connect(tcpsocket,&QTcpSocket::connected,
            [=]()
    {
        ui->textEditRead->setText("成功和服務器建立好鏈接");
    });
    connect(tcpsocket,&QTcpSocket::readyRead,
            [=]()
    {
        //獲取對方發送的內容
        QByteArray array = tcpsocket->readAll();
        //追加到編輯區中
        ui->textEditRead->append(array);
    });
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_buttonConnect_clicked()
{
    //1.獲取服務器ip和端口
    QString ip = ui->lineEditIP->text();
    qint16 port = ui->lineEditPort->text().toInt();

    //2.主動和服務器建立鏈接
    tcpsocket->connectToHost(QHostAddress(ip),port);
}

void Widget::on_buttonSend_clicked()
{
    //獲取編框內容
    QString str = ui->textEditWrite->toPlainText();
    //發送數據
    tcpsocket->write(str.toUtf8().data());
}
void Widget::on_buttonClose_clicked()
{
    //主動和對方斷開連接
    tcpsocket->disconnectFromHost();
    tcpsocket->close();
}

參考:QT - 創建TCP Socket通信

黑馬Qt筆記

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM