Qt中的TCP服務端和客戶端互發消息


Qt中的TCP服務端和客戶端互發消息

在這里插入圖片描述

作者:hackett
微信公眾號:加班猿

 

廢話不多說,上演示效果

由於我們用到socketLamda表達式,所以工程.pro文件需要添加對應的庫

image-20201111195456610

為了方便,main.cpp中讓程序顯示兩個Widget窗口,程序運行起來就可以測試

 ServerWidget w;
 w.show();
 ClientWidget w2;
 w2.show();

一、服務端

服務端的UI界面布局:

2個PushButton(send,close)

2個textEdit(發送內容,接收內容)

image-20201111201341091

新建一個監聽套接字,監聽端口號為9999的IP,等待連接,有連接過來提示成功連接同時服務端讀就緒

  //監聽套接字,指定父對象,讓其自動回收空間
 tcpServer = new QTcpServer(this);
 
 tcpServer->listen(QHostAddress::Any, 9999);
 
 setWindowTitle("服務器: 9999");
 
 //newConnection代表有新的連接
 connect(tcpServer, &QTcpServer::newConnection,
        [=]()
        {
             //取出建立好連接的套接字
             tcpSocket = tcpServer->nextPendingConnection();
 
             //獲取對方的IP和端口
             QString ip = tcpSocket->peerAddress().toString();
             quint16 port = tcpSocket->peerPort();
             QString temp = QString("[%1:%2]:成功連接").arg(ip).arg(port);
             ui->textEditRead->setText(temp);
 
             //readyRead代表讀就緒
             connect(tcpSocket, &QTcpSocket::readyRead,
                    [=]()
                    {
                         //從通信套接字中取出內容
                         QByteArray array = tcpSocket->readAll();
                         ui->textEditRead->append(array);
                    }
                    );
        }
        );

二、客戶端

客戶端的UI界面布局:

3個PushButton(connect,send,close)

2個lineEdit(端口號,IP)

2個textEdit(發送內容,接收內容)

image-20201111200014145

客戶端連接按鈕主動與服務端建立連接

 void ClientWidget::on_buttonConnect_clicked()
 {
     //獲取服務器ip和端口
     QString ip = ui->lineEditIP->text();
     qint16 port = ui->lineEditPort->text().toInt();
 
     //主動和服務器建立連接
     tcpSocket->connectToHost(QHostAddress(ip), port);
 
 }

連接成功后會觸發connected,提示"成功和服務器建立好連接"同時客戶端讀就緒

 //分配空間,指定父對象
 tcpSocket = new QTcpSocket(this);
 
 setWindowTitle("客戶端");
 
 
 connect(tcpSocket, &QTcpSocket::connected,
        [=]()
        {
             ui->textEditRead->setText("成功和服務器建立好連接");
        }
        );
 
 connect(tcpSocket, &QTcpSocket::readyRead,
        [=]()
        {
             //獲取對方發送的內容
             QByteArray array = tcpSocket->readAll();
             //追加到編輯區中
             ui->textEditRead->append(array);
        }
 
        );

源碼

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"
 #include <QDebug>
 
 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, 9999);
 
     setWindowTitle("服務器: 9999");
 
     //newConnection代表有新的連接
     connect(tcpServer, &QTcpServer::newConnection,
            [=]()
            {
                 //取出建立好連接的套接字
                 tcpSocket = tcpServer->nextPendingConnection();
 
                 //獲取對方的IP和端口
                 QString ip = tcpSocket->peerAddress().toString();
                 quint16 port = tcpSocket->peerPort();
                 QString temp = QString("[%1:%2]:成功連接").arg(ip).arg(port);
                 ui->textEditRead->setText(temp);
 
                 //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;
 }
 

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);
 
     setWindowTitle("客戶端");
 
 
     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->write( str.toUtf8().data() );
 
 }
 
 void ClientWidget::on_buttonClose_clicked()
 {
     //主動和對方斷開連接
     tcpSocket->disconnectFromHost();
     tcpSocket->close();
 }

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

如果你覺得文章還不錯,記得"點贊關注"

關注我的微信公眾號【 加班猿 】可以獲取更多內容

 在這里插入圖片描述


免責聲明!

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



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