TCP通訊軟體開發--Qt

2020-10-09 18:01:15

軟體功能描述

(1)TCP server 實現根據 「IP地址」 和 「埠號」 開啟伺服器,監聽連線,收發資料功能。
(2)TCP client 實現根據 「IP地址」 和 「埠號」 連線伺服器,收發資料功能。

目前只實現了一對一通訊,只能有一個client,可通過動態建立socket的方式實現多個client。

實現步驟

建立工程

開發環境:Qt Creator 5.12.8 qt-opensource-windows-x86-5.12.8
下圖中沒展示的步驟使用預設設定即可。

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

新增client

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
現在就有了兩個ui
在這裡插入圖片描述

ui設計

Server 介面:

在這裡插入圖片描述

Client介面:
在這裡插入圖片描述

控制程式

TCP.pro

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    client.cpp \
    main.cpp \
    server.cpp

HEADERS += \
    client.h \
    server.h

FORMS += \
    client.ui \
    server.ui

CONFIG += c++11


# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

client.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>

namespace Ui {
class Client;
}

class Client : public QWidget
{
    Q_OBJECT

public:
    explicit Client(QWidget *parent = nullptr);
    ~Client();

private:
    Ui::Client *ui;
    //QTcpServer* server;//監聽的通訊端
    QTcpSocket* client;//通訊的通訊端
};

#endif // CLIENT_H

server.h

#ifndef SERVER_H
#define SERVER_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class Server; }
QT_END_NAMESPACE

class Server : public QWidget
{
    Q_OBJECT

public:
    Server(QWidget *parent = nullptr);
    ~Server();

private:
    Ui::Server *ui;
    QTcpServer* server;//監聽的通訊端
    QTcpSocket* conn;//通訊的通訊端
};
#endif // SERVER_H

client.cpp

#include "client.h"
#include "ui_client.h"

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

    //ui init
    ui->IP->setText("192.168.50.116");
    ui->PORT->setText("12321");
    ui->state->setText("狀態:未連線");

    connect(ui->Connect, &QPushButton::clicked, this, [=]()
    {
        // init
        client = new QTcpSocket(this);
        //連線伺服器
        client->connectToHost(QHostAddress(ui->IP->text()),ui->PORT->text().toInt());
        ui->state->setText("狀態:已連線");
        ui->record->append("已連線到伺服器---IP:" + ui->IP->text() + "  埠:" + ui->PORT->text());

        //接收資料
        connect(client, &QTcpSocket::readyRead, this, [=]()
        {
            QByteArray array = client->readAll();
            ui->record->append("Server: " + array);
        });
        //傳送
        connect(ui->send, &QPushButton::clicked, this, [=]()
        {
            //傳送資料
            client->write(ui->msg->toPlainText().toUtf8());
            ui->record->append("Client: " + ui->msg->toPlainText());
            //clear
            //ui->textEdit_2->clear();
        });

    });
}

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

server.cpp

#include "server.h"
#include "ui_server.h"

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

    //ui init
    ui->IP->setText("192.168.50.116");
    ui->PORT->setText("12321");
    ui->state->setText("狀態:未開啟");

    connect(ui->OpenServer, &QPushButton::clicked, this, [=]()
    {
        //範例化
        server = new QTcpServer(this);
        //監聽
        server->listen(QHostAddress(ui->IP->text()),ui->PORT->text().toInt());
        ui->state->setText("狀態:已開啟");

        //新的連線
        connect(server, &QTcpServer::newConnection, this, [=]()
        {
            //接收使用者端的通訊端物件accept
            // sock_addr 結構體 == 類 QTcpSocket
            conn = server->nextPendingConnection();
            QString str;
            ui->record->append("使用者端接入---IP: " + conn->peerAddress().toString() +"  埠:"+ str.sprintf("%d", (conn->peerPort())));

            //接收資料
            connect(conn, &QTcpSocket::readyRead, this, [=]()
            {
                QByteArray array = conn->readAll();
                ui->record->append("Client: " + array);
            });

        });

        //傳送
        connect(ui->send, &QPushButton::clicked, this, [=]()
        {
            //傳送資料
            conn->write(ui->msg->toPlainText().toUtf8());
            //char data[1024];data[0]=0xeb;data[1]=0x90;
            //conn->write(data,1024);
            ui->record->append("Server: " + ui->msg->toPlainText());
            //clear
            //ui->textEdit_2->clear();
        });
    });

}

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


main.cpp

#include "server.h"
#include "client.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Server w;
    w.setWindowTitle("TCP Server");
    w.show();

    Client c;
    c.setWindowTitle("TCP Client");
    c.show();

    return a.exec();
}

介面展示

在這裡插入圖片描述