qt network programming

catalogue

Network programming

Socket

socket under qt

qt TCP connection process

Example of file transmission from TCP server to client:

UDP for qt

UDP unicast example of qt:

UDP broadcast and multicast (multicast)

Network programming

Three elements: IP address, port number and communication protocol

IP address: computers in the network use IP addresses for unique identification. There are two types of IP addresses: IPv4 and IPv6. IPv4 adopts decimal or binary representation. Decimal is a common representation, such as 192.158.147.3. IPv6 is expressed in hexadecimal

Port number: an integer number label used to distinguish different applications in a computer

0 ~ 1024 is the port number used or reserved by the system, and 0 ~ 65535 is the valid port number, that is, when we want to define the port number for some programs, we should select an integer number in the range of 1024 ~ 65535.

MySQL port number is 3306, SQL server port number is 1433, and Oracle port number is 1521.

Communication protocol is the rule of network communication, which is divided into TCP protocol (connection oriented) and UDP protocol (data transmission oriented)

Socket

Also known as "socket", it is a convention or a way of communication between computers

Through the socket agreement, the computer can accept the data of other computers or send data to other computers. There are many special functions to read and write files of other computers

"Everything is a file", which can be operated in the "open – > read / write/read – > close" mode.
That is, socket is a special file, and some socket functions operate on it (read / write IO, open and close).
The Socket() function returns an integer Socket descriptor. Subsequent operations such as connection establishment and data transmission are implemented through the Socket.

socket under qt

TCP generally sends files, audio, etc., and UDP generally sends text

QT       += network

TCP under LINUX:

For network programming under LINUX, we can use the unified SOCKET interface provided by LINUX. However, this method involves too many structures, such as IP address, port conversion, etc. The SOCKET provided in QT completely uses the class encapsulation mechanism, so that users do not need to contact various underlying structures for operation. Moreover, it uses QT's own signal and slot mechanism to make the program easier to understand.

qt TCP connection process

No matter who sends the message, the other party's communication socket triggers readyRead() after success

Example of file transmission from TCP server to client:

Flow chart of document transfer

 

 

The server ui is as follows:

public:
void sendData();//Send data

private:
    QTcpServer *tcpServer;//listening socket 
    QTcpSocket *tcpSocket;//Communication socket
    QFile file;//File object
    QString filename;
    qint64 fileSize;
    qint64 sendSize;//The size of the file that has been sent
    QTimer timer;//timer

In constructor

    
    tcpServer =new QTcpServer(this);
    tcpServer->listen(QHostAddress::Any,8888);//Listen to all web addresses and set port 8888 of the server
    
//newConnection is automatically triggered when the connection is successful
connect(tcpServer,&QTcpServer::newConnection,
            [=]()
    {
        tcpSocket =tcpServer->nextPendingConnection();//Get the connected socket
        QString ip=tcpSocket->peerAddress().toString();
        qint16 port =tcpSocket->peerPort();
        QString temp =QString("[%1:%2]:zhaoyi Successfully connected").arg(ip).arg(port);
        ui->textEditread->setText(temp);   //Displays the ip and port of the other party       
    }
            );
      //Turn off the timer and send data
       connect(&timer,&QTimer::timeout,
                [=]()
       {
             timer.stop();
              sendData();
        }
           );


}
//Selected file
void server::on_pushButtonxuanwj_clicked()
{
    QString filepath=QFileDialog::getOpenFileName(this,"open","../");
    if(filepath.isEmpty()==false)//If the selected path is valid
    {
        //initialization
        filename.clear();
        fileSize=0;
        //Get file information
        QFileInfo info(filepath);
        filename=info.fileName();
        fileSize=info.size();

        sendSize=0;//Send file size

        file.setFileName(filepath);//specify a filename

        bool isok=file.open(QIODevice::ReadOnly);//Read only open
        if(isok==false)
        {
            qDebug()<<"Read only failure";
        }
        ui->textEdit->append(filepath);//Prompt file path
    }
    else
    {
        qDebug()<<"Failed to read file";
    }
}

//Send documents
void server::on_pushButtonxuan_clicked()
{
    //First issue header information file name ## file size
    QString head=QString("%1##%2").arg(filename).arg(fileSize);
    qint64 len=tcpSocket->write(head.toUtf8());

    if(len>0)//If the header file information is sent successfully
    {
        timer.start(100);//Send real files at regular intervals to prevent TCP packets from sticking
    }
    else
    {
        qDebug()<<"head fail in send";
        file.close();
    }
}
void server::sendData()
{
    qint64 len=0;
    do
    {
        char buf[4*1024]={0};//Hair size
        len=0;

        //How much to read, how much to send
        len=file.read(buf,sizeof(buf));
        len=tcpSocket->write(buf,len);

        sendSize+=len;//Cumulative
    }while(len>0);//Judge to finish reading

        if(sendSize == fileSize)
        {
            ui->textEdit->append("File sent");
            file.close();

            tcpSocket->disconnectFromHost();
            tcpSocket->close();
        }
}

The client ui is as follows:

private:
    QTcpSocket *tcpSocket;
    QFile file;//File object
    QString filename;
    qint64 fileSize;
    qint64 recvSize;//The size of the file has been accepted
    bool isStart;

 

    tcpSocket=new QTcpSocket(this);
    isStart=true;
    recvSize=0;

    connect(tcpSocket,&QTcpSocket::readyRead,
            [=]()
    {
        QByteArray buf=tcpSocket->readAll();//Take out everything
        if(isStart==true)
        {
            isStart=false;
            //Parsing header file information
            /*section The function of is to take out a continuous part from a string
             Start from location ID, left to right: 0, 1, 2, 3, 4, 5  */
            filename=QString(buf).section("##",0,0);
            fileSize=QString(buf).section("##",1,1).toInt();//QString->int


            //Open file
            file.setFileName(filename);
            bool isok=file.open(QIODevice::WriteOnly);
            if(isok==false)
            {
                qDebug()<<"write error";
            }
        }
        else//Send real file data
        {

                qint64 len=file.write(buf);//Write data
                recvSize+=len;

                if(recvSize==fileSize)
                {
                    file.close();
                    QMessageBox::information(this,"ok","write in ok");
                    tcpSocket->disconnectFromHost();
                    tcpSocket->close();
                }
        }
    }
            );
//connect
void client::on_pushButtonlianjie_clicked()
{
    QString ip=ui->lineEditIP->text();
    qint16 port=ui->lineEditport->text().toInt();
    tcpSocket->connectToHost(QHostAddress(ip),port);

}

UDP under LINUX

UDP for qt

    

UDP unicast example of qt:

It is only sent to another UDP client with specified address and port. It is one-to-one data transmission

.cpp

    udpSocket =new QUdpSocket(this);
    udpSocket->bind(8888);
    setWindowTitle("8888");//title
    connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::dealMsg);//Custom slot function

//Accept the data sent by the other party
    void Widget::dealMsg()
{
    char buf[1024]={0};
    QHostAddress cliAddr;
    quint16 port;
//The other party connects to "I", and "I" displays the other party's ip, port number and sent data
    qint64 len= udpSocket->readDatagram(buf,sizeof(buf),&cliAddr,&port);
    if(len>0)
    {
        QString str =QString("[%1:%2] %3").arg(cliAddr.toString()).arg(port).arg(buf);
        ui->textEdit->setText(str);
    }
}


//send control
void Widget::on_Buttonsend_clicked()
{
    //Before using UDP protocol for information transmission, there is no need to establish a connection, just give the other party's ip address and port number
    QString ip =ui->lineEditip->text();
    qint16 port =ui->lineEditport->text().toInt();
    QString str =ui->textEdit->toPlainText();
    udpSocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port);
}

UDP broadcast and multicast (multicast)

TCP only has point-to-point, and UDP has the concepts of point-to-point, multicast and broadcast

There is no need to establish a connection before using UDP protocol for information transmission. In other words, the client sends information to the server. The client only needs to give the ip address and port number of the server, and then encapsulate the information into a message to be sent and send it. As for whether the server exists or can receive the message, the client doesn't care at all.  

For broadcasting, all other UDP clients in the same network can receive it. Unicast and broadcast are basically implemented in the same way, except that the target IP address settings of datagrams are different. When broadcasting messages, you only need to replace the target address with a special address, that is, broadcast address QHostAddress::Broadcast, which is generally 255.255.255.255

For multicast, all members in the group (multicast group specified by multicast IP address) can receive. Using multicast address, other port binding and datagram sending and receiving functions are exactly the same as unicast UDP.

Multicast (one-to-one group):

When multiple clients join a multicast group defined by a multicast address, the client sends datagrams to the multicast address and port, and all members of the group can receive them

224.0.0.0 ~ 224.0.0.255 are reserved multicast addresses (permanent group addresses). Address 224.0.0.0 is reserved for allocation, and other addresses are used by routing protocols
224.0.1.0 ~ 224.0.1.255 are public multicast addresses that can be used on the internet
224.0.2.0 ~ 238.255.255.255 are multicast addresses (temporary group addresses) available to users, which are valid in the whole network
239.0.0.0 ~ 239.255.255.255 are local management multicast addresses, which are valid only in a specific local range


 

Keywords: network Qt

Added by sofasurfer on Mon, 17 Jan 2022 17:39:52 +0200