TCP UDP for QT Network Communication

Keywords: Qt udp TCP/IP

The lambada expression is supported in higher versions of QT, but the line "CONFIG += C++11" needs to be added to the file "projectName.pro". The new and old forms are documented below.

1. TCP

1. Complete Project

  • Connections between signals and slot functions in tcpserver.cpp in this project use the connect() function in a form supported by most older versions and are manually connected in this file
  • The connection between the signal in tcpsocket.cpp and the slot function is automatic, that is, from the device in the ui interface, the right mouse button goes to the slot function. There are also manually connected
  • When connecting manually, note that the required functions need to be declared under "private slots:" in the corresponding header file
  • connect(a,SIGNAL(b),c,SLOT(d)); My own way of understanding and memory: after a receives a signal like b, you need to let C do such a function as D. It is equivalent to interrupt in single-chip computer: receiving an external signal, triggering the interrupt function, and completing the corresponding tasks in the interrupt function.



    ==Note: Devices used in this project: IP input boxes and Port input boxes use Input Widgets---->Line Edit; The two boxes in the middle are above the message log box and below the information input box, which use Input Widgets---->Text Edit; The bottom three buttons use Buttons---->Push Button


Modify Name:
1: sIP
2:sPort
3:record
4:msg
5:openBt
6:closeBt
7:sendBt





The next two pictures capture the full picture

"tcpserver.cpp" All the code in this file is given below

#include "tcpserver.h"
#include "ui_tcpserver.h"



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

    ui->sIP->setText("127.0.0.1");
    ui->sPort->setText("8888");

    server = new QTcpServer(this);
    conn = new QTcpSocket(this);



    //Listening should be done all the time and may result in one click after being associated with the button's slot signal.
    //Or it may not, because the information received is written inside, and the information received can be written inside as long as it is normal
     server->listen(QHostAddress(ui->sIP->text()),ui->sPort->text().toInt());
     connect(server,SIGNAL(newConnection()),this,SLOT(conn_slot()));

    //All manual associations on the server side and all automatic associations on the client side

    //Click the Open button to prompt for information to open and receive information
    //connect(ui->openBt,&QPushButton::clicked,this,SLOT("openBt_slot()"));

    //Disconnect by clicking the Close button

    //connect(ui->closeBt,&QPushButton::clicked,this,SLOT("closeBt_slot()"));
  connect(ui->closeBt,SIGNAL(clicked()),this,SLOT(closeBt_slot()));
}

void TCPServer:: conn_slot(){
    conn = server->nextPendingConnection();
    connect(ui->openBt,SIGNAL(clicked()),this,SLOT(openBt_slot()));
}
void TCPServer::openBt_slot(){

    //Associated Receive Signal
      connect(conn,SIGNAL(readyRead()),this,SLOT(readData_slot()));
      connect(ui->sendBt,SIGNAL(clicked()),this,SLOT(sendBt_slot()));
    QMessageBox::information(this,"Tips","Open Successfully");
}
void TCPServer:: closeBt_slot(){
    conn->close();
    QMessageBox::information(this,"Tips","Shutdown succeeded");
}

void TCPServer:: readData_slot(){
    ui->record->append(conn->readAll());
    QMessageBox::information(this,"Tips","Read data successfully");
}

void TCPServer::sendBt_slot(){
    //Send information

    conn->write(ui->msg->toPlainText().toUtf8());
    ui->record->append("server say:"+ui->msg->toPlainText());
    //QMessageBox::information(this, "prompt", "read data successfully");
}


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


All the code in "tcpserver.h" is given below

#ifndef TCPSERVER_H
#define TCPSERVER_H

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

namespace Ui {
class TCPServer;
}

class TCPServer : public QWidget
{
    Q_OBJECT

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

 private  slots:
    void openBt_slot();
    void sendBt_slot();
    void readData_slot();
    void closeBt_slot();
    void conn_slot();
private:
    Ui::TCPServer *ui;
    QTcpServer *server;//server for listening
    QTcpSocket *conn;//conn for communication
};

#endif // TCPSERVER_H



The "tcpsocket.cpp" code is as follows

#include "tcpsocket.h"
#include "ui_tcpsocket.h"

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

    ui->sIP->setText("127.0.0.1");
    ui->sPort->setText("8888");

    conn = new QTcpSocket(this);

}

TCPSocket::~TCPSocket()
{
    delete ui;

}

void TCPSocket::on_openBt_clicked()
{
    //Connect to Server
    conn->connectToHost(ui->sIP->text(),ui->sPort->text().toInt());
    //Open Client to Receive Information
    connect(conn,SIGNAL(readyRead()),this,SLOT(readyRead_slot()));

}

void TCPSocket::on_closeBt_clicked()
{

}

void TCPSocket::on_sendBt_clicked()
{
    conn->write(ui->msg->toPlainText().toUtf8());
    ui->record->append(ui->msg->toPlainText());
}

void TCPSocket:: readyRead_slot(){
    ui->record->append(conn->readAll());
}

"tcpsocket.h" code

#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include <QWidget>
#include <QTcpSocket>
#include <QMessageBox>

namespace Ui {
class TCPSocket;
}

class TCPSocket : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_openBt_clicked();

    void on_closeBt_clicked();

    void on_sendBt_clicked();
    void readyRead_slot();

private:
    Ui::TCPSocket *ui;
    QTcpSocket *conn;
};

#endif // TCPSOCKET_H


The "main.cpp" code is as follows

#include "tcpserver.h"
#include <QApplication>
#include "tcpsocket.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TCPServer s;
    s.setWindowTitle("server");
    s.show();

    TCPSocket c;
    c.setWindowTitle("client");
    c.show();

    return a.exec();
}

The results are as follows:

==2. Complete project supporting new form of lambada function


//server.cpp file

#include "serval.h"
#include "ui_serval.h"
#include <QHostAddress>


Serval::Serval(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Serval)
{
    ui->setupUi(this);
    //Initialization
    ui->sIP->setText("127.0.0.1");
    ui->sPort->setText("8888");
    //instantiation
    server = new QTcpServer;

    //Monitor
   server->listen(QHostAddress(ui->sIP->text()),ui->sPort->text().toInt());
     qDebug("server 11111111111111111111111111");
    //There will be a newConnection() signal waiting for the connection
    connect(server,&QTcpServer::newConnection,this,[=](){
  qDebug("server 222222222222222222222222222222");
        //Get Sockets
        conn = server->nextPendingConnection();//The socket information returned is the other party's socket information and can communicate properly
        ui->record->append("have a new link.....");
  qDebug("server 33333333333333333333333333333333");
        //Receive information
        connect(conn,&QTcpSocket::readyRead,this,[=](){
  qDebug("server 4444444444444444444444444444444");
            //Receive information
           QByteArray arry= conn->readAll();
           ui->record->append(arry);

        });
  qDebug("server 5555555555555555555555555555555555555555");
    });
  qDebug("server 6666666666666666666666666666666666");


    //Send out
    connect(ui->sendBt,&QPushButton::pressed,this,[=](){
  qDebug("server 777777777777777777777777777777777777777");
        //Send information
        conn->write(ui->msg->toPlainText().toUtf8());
        ui->record->append("sever say"+ui->msg->toPlainText());
        //Empty message in send box
        ui->msg->clear();
   qDebug("server 88888888888888888888888888888888888888888888");
    });


  qDebug("server 9999999999999999999999999999999999999999");
}

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


//server.h file

#ifndef SERVAL_H
#define SERVAL_H

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


namespace Ui {
class Serval;
}

class Serval : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Serval *ui;
    QTcpServer  *server;//Monitor
    QTcpSocket *conn;//Signal communication
};

#endif // SERVAL_H



//client.cpp file

#include "client.h"
#include "ui_client.h"
#include <QHostAddress>


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

    ui->sIP->setText("127.0.0.1");
    ui->sPort->setText("8888");
      qDebug("client 11111111111111111111111111");
    //Connect to Server
    client->connectToHost(ui->sIP->text(),ui->sPort->text().toInt());

      qDebug("client 22222222222222222222222222222");
    connect(ui->sendBt,&QPushButton::pressed,this,[=](){
      qDebug("client 3333333333333333333333333333333");
        //Send out
        client->write(ui->msg->toPlainText().toUtf8());
        ui->record->append("client say:"+ui->msg->toPlainText());
      qDebug("client 444444444444444444444444444");
    });
      qDebug("client 5555555555555555555555555555555");
    //Receive information
    connect(client,&QTcpSocket::readyRead,this,[=](){

       qDebug("client 6666666666666666666666666666666");
       QByteArray arry=client->readAll();
       ui->record->append(arry);
     qDebug("client 7777777777777777777777777777777777");
    });
      qDebug("client 8888888888888888888888888888888888");
}

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


//client.h file

#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include <QTcpSocket>
#include <QDebug>

namespace Ui {
class Client;
}

class Client : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Client *ui;
    QTcpSocket *client;

};

#endif // CLIENT_H

//main.cpp file

#include "serval.h"
#include <QApplication>

#include "client.h"


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

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

    return a.exec();
}

//Run as follows

2. UDP

Same as the previous implementation with a lower version

  • Note: The following code is made against a video on the beeper.

The.cpp file is as follows

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>

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

}

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


void Widget::readyRead_slot(){

    while(udpSocket->hasPendingDatagrams()){
        QByteArray arry;
        arry.resize(udpSocket->hasPendingDatagrams());
        udpSocket->readDatagram(arry.data(),arry.size());

        QString buf;
        buf = arry.data();
        ui->recvEdit->appendPlainText(buf);
        ui->recvEdit->appendPlainText(buf);
    }
}

void Widget::on_openBt_clicked()
{
    if(udpSocket->bind(ui->localPort->text().toUInt())==true){
        QMessageBox::information(this,"Tips","Success");
    }else{
        QMessageBox::information(this,"Tips","fail");
    }
    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot()));

}


void Widget::on_sendBt_clicked()
{
    quint16 port;
    QString sendbuff;
    QHostAddress address;

    address.setAddress(ui->aimIp->text());
    sendbuff = ui->sendEdit->text();
    port = ui->aimPort->text().toUInt();

    udpSocket->writeDatagram(sendbuff.toLocal8Bit().data(),sendbuff.length(),address,port);
}

void Widget::on_closeBt_clicked()
{
    udpSocket->close();
    QMessageBox::information(this,"Tips","Shutdown succeeded");
}


//.h file as follows

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>
#include <QString>
#include <QHostAddress>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

    QUdpSocket *udpSocket;
private slots:
    void on_openBt_clicked();
    void readyRead_slot();

    void on_sendBt_clicked();

    void on_closeBt_clicked();

private:
    Ui::Widget *ui;

};

#endif // WIDGET_H

//main.cpp

#include "widget.h"
#include <QApplication>

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

    return a.exec();
}

//Run as follows
Connected network tester is communicable

2. Support lambada writing




//server.cpp

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

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

    udp1 = new QUdpSocket(this);


    //Initialize IP and Port
    ui->cIP->setText("127.0.0.1");
    ui->cPort->setText("8888");
    ui->sPort->setText("6666");
    //Bind to your own port
    udp1->bind(ui->sPort->text().toInt());



    connect(ui->sendBt,&QPushButton::pressed,this,[=](){

        /*Send information
        In the ui interface, the info box msg uses Input Widget--->Text Edit, and the toPlainText() method is used to convert text.
         cIP and cPort use the Input Widget----> Line Edit, while text() is used to convert text.
         Note: When binding a port, it is the binding's own port. When sending, it specifies the IP address and port number of the other party.
        */
        udp1->writeDatagram(ui->msg->toPlainText().toUtf8(),QHostAddress(ui->cIP->text()),ui->cPort->text().toInt());

        ui->record->append("server say:"+ui->msg->toPlainText());
       // ui->record->clear();
    });



//    connect(ui->openReceveBt,&QPushButton::clicked,this,[=](){
//       // QMessageBox::information(this,'prompt','open receive window successfully');
//        qDebug("111111111111111111111111111111111111111");
        connect(udp1,&QUdpSocket::readyRead,this,[=](){
//qDebug("222222222222222222222222222222222");
            quint64 size = udp1->pendingDatagramSize();
            QByteArray array(size,0);
            udp1->readDatagram(array.data(),size);
            ui->record->append(array);
        });
//    });
}

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


/*
 //If you add a button, there will be a problem when the server receives information.
   connect(ui->openReceveBt,&QPushButton::clicked,this,[=](){
       // QMessageBox::information(this,'prompt','open receive window successfully');
        qDebug("111111111111111111111111111111111111111");
        connect(udp1,&QUdpSocket::readyRead,this,[=](){
qDebug("222222222222222222222222222222222");
            quint64 size = udp1->pendingDatagramSize();
            QByteArray array(size,0);
            udp1->readDatagram(array.data(),size);
            ui->record->append(array);
        });
    });
 * /



//server.h

#ifndef SERVER_H
#define SERVER_H

#include <QWidget>
#include<QUdpSocket>
#include<QMessageBox>
#include <QDebug>

namespace Ui {
class Server;
}

class Server : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Server *ui;
    QUdpSocket *udp1;
};

#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);

    udp2 = new QUdpSocket(this);
    //Initialize IP and Port
    ui->sIP->setText("127.0.0.1");

    ui->sPort->setText("6666");
    ui->cPort->setText("8888");
    //Bind to your own port
    udp2->bind(ui->cPort->text().toInt());



    connect(ui->sendBt,&QPushButton::pressed,this,[=](){

        /*Send information
        In the ui interface, the info box msg uses Input Widget--->Text Edit, and the toPlainText() method is used to convert text.
         cIP and cPort use the Input Widget----> Line Edit, while text() is used to convert text.
         Note: When binding a port, it is the binding's own port. When sending, it specifies the IP address and port number of the other party.
        */
        udp2->writeDatagram(ui->msg->toPlainText().toUtf8(),QHostAddress(ui->sIP->text()),ui->sPort->text().toInt());

        ui->record->append("client say:"+ui->msg->toPlainText());
       // ui->record->clear();
    });

    connect(udp2,&QUdpSocket::readyRead,this,[=](){

        quint64 size = udp2->pendingDatagramSize();
        QByteArray array(size,0);
        udp2->readDatagram(array.data(),size);
        ui->record->append(array);
    });
}

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

//server.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include<QUdpSocket>

namespace Ui {
class Client;
}

class Client : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Client *ui;
    QUdpSocket *udp2;
};

#endif // CLIENT_H

//main.cpp

#include "server.h"
#include <QApplication>
#include "client.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Server s;
    s.setWindowTitle("sever");
    s.show();

    Client c;
    c.setWindowTitle("client");
    c.show();
    return a.exec();
}

//Run as follows

Posted by vtolbert on Fri, 12 Nov 2021 12:24:24 -0800