Qt + TCP通信過程 + 客戶端與服務端軟件的制作


Qt的通信過程如下圖:

 

工程目錄:

在工程目錄中clientwidget類的添加過程,點擊工程名字右鍵添加文件 如下:

                                 

                                        1

              

                                    2

                

                                      3

                  

                                          4

Tcp.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2019-07-07T08:28:26
#
#-------------------------------------------------

QT       += core gui  network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Tcp
TEMPLATE = app


SOURCES += main.cpp\
        serverwidget.cpp \
    clientwidget.cpp

HEADERS  += serverwidget.h \
    clientwidget.h

FORMS    += serverwidget.ui \
    clientwidget.ui

CONFIG += C++11

 

 

clientwidget.h:

#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H

#include <QWidget>

#include <QTcpSocket>//僅需通信套接字

namespace Ui {
class ClientWidget;
}

class ClientWidget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_buttonConnect_clicked();

    void on_buttonSend_clicked();

    void on_buttonClose_clicked();
    
private:
    Ui::ClientWidget *ui;

    QTcpSocket  *tcpSocket;//通信套接字
};

#endif // CLIENTWIDGET_H

 

 

serverwidget.h:

#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

 

 

clientwidget.cpp:

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QHostAddress>
ClientWidget::ClientWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ClientWidget)
{
    ui->setupUi(this);

    tcpSocket = NULL;

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


    connect(tcpSocket,&QTcpSocket::connected,[=](){

        ui->textEditRead->setText("成功和服務器建立好連接");

    });

    connect(tcpSocket,&QTcpSocket::readyRead,[=](){
        //獲取對方發送的內容
        QByteArray array = tcpSocket->readAll();

        //追加到編輯區中
        ui->textEditRead->append(array);

    });

}

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

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

    //主動和服務器建立連接
    tcpSocket->connectToHost(QHostAddress(ip),port);

}



void ClientWidget::on_buttonSend_clicked()
{
    //獲取編輯區的內容
    QString str = ui->textEditWrite->toPlainText();

    //發送數據,使用套接字是tcpSocket
    tcpSocket->write(str.toUtf8().data());
}

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

    tcpSocket = NULL;
}

 

 

main.cpp:

#include "serverwidget.h"
#include <QApplication>
#include "clientwidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ServerWidget w;
    w.show();

//添加的新窗口
    ClientWidget w2;
    w2.show();

    return a.exec();
}

 

 

serverwidget.cpp:

#include "serverwidget.h"
#include "ui_serverwidget.h"

ServerWidget::ServerWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ServerWidget)
{
    ui->setupUi(this);

    tcpServer = NULL;
    tcpSocket = NULL;

    //監聽套接字   指定父對象的目的,讓其自動回收空間
    tcpServer = new QTcpServer(this);

    tcpServer->listen(QHostAddress::Any,8888);

    setWindowTitle("服務器:8888");

    connect(tcpServer,&QTcpServer::newConnection,[=](){
        //取出建立好連接的的套接字
        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);

            /*注意這里的connect的位置,一定在建立好連接后,
             * 不然會出現野指針的錯誤,前面定義的QTcpSocket  *tcpSocket;
             * 而程序會先從構造函數執行的,還沒有執行到定義的QTcpSocket  *tcpSocket指針。
            */
            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;
}

 

 

clientwidget.ui:

serverwidget.ui:

 


免責聲明!

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



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