QT--realize TCP communication

Reminder: This article is a study record, if there are any mistakes, please contact the author, and be taught with humility.


foreword

Life comes and goes, don't wait for the day to come.


1. TCP protocol

Transmission Control Protocol (TCP, Transmission Control Protocol) is a connection-oriented, reliable, byte stream-based transport layer communication protocol.

Advantages:
(1) Flow-based method;
(2) Connection-oriented;
(3) Reliable communication method;
(4) Minimize the bandwidth overhead of the system due to retransmission when the network condition is not good;
(5) Communication connection Maintenance is oriented to the two endpoints of the communication, regardless of intermediate network segments and nodes.

Details can be found at: "TCP URL"

In order to meet these characteristics of the TCP protocol, the TCP protocol has made the following regulations:
①Data fragmentation: fragment user data at the sending end and reassemble at the receiving end, and TCP determines the fragment size and controls fragmentation and reassembly ;
② Arrival confirmation: When the receiving end receives the fragmented data, it sends an acknowledgment to the sending end according to the serial number of the fragmented data;
③ Timeout retransmission: The sender starts the timeout timer when sending Receive the corresponding confirmation and resend the fragment;
④Sliding window: The size of the receiving buffer space of each party in the TCP connection is fixed, and the receiving end only allows the other end to send the data that the receiving end buffer can accept. Provide flow control on the network to prevent the faster host from overflowing the buffer of the slower host;
⑤ Out-of-order processing: TCP fragments transmitted as IP datagrams may arrive out of order, and TCP will reorder the received data, The received data is handed over to the application layer in the correct order;
⑥Repeated processing: TCP fragments transmitted as IP datagrams will be repeated, and the receiving end of TCP must discard the repeated data; ⑦Data verification
: TCP will keep it The checksum of the header and data, which is an end-to-end checksum, aims to detect any changes in the data during transmission. If there is an error in the checksum of the received fragment, TCP will discard the fragment, and does not confirm receipt of the segment, causing the peer to time out and resend.

"The Legendary TCP Three-way Handshake"
insert image description here
The host computer acts as a client, actively connects to the server, sends data, and receives data.
Simple understanding:
ASend: I'm going to send you a message, are you ready?
B send: I'm ready, send it!
A send: OK, then I send it.
Then A starts sending.
This is the three-way handshake at the level of understanding.
The following will be a simple example related to QT.

Two, TCP communication steps

1. Implementation process of TCP server

Key points:
A. Call listen to listen to the port

B. The connection signal newConnection, call nextPendingConnection in the slot function to get the connected socket.

(1) .h import header file

#include <QTcpServer>
#include <QTcpSocket>

(2) Create a QTcpServer object as a listening socket;

QTcpServer *m_s;
QTcpSocket *m_tcp;

in the constructor new

//放在构造函数中
m_s = new QTcpServer(this);

(3) Use the listen() method to monitor the ip and port of the network card

void MainWindow::on_bt_listen_clicked()
{
    
    
    unsigned short port = ui->lineEdit->text().toUShort();
    bool ret =m_s->listen(QHostAddress::Any, port);
    if(ret)
    {
    
    
        ui->textEdit->append("启动服务器成功");
    }
    else {
    
    
        ui->textEdit->append("error");
    }
    qDebug()<<ret<<m_s->errorString();
}

(4) Send information

void MainWindow::on_bt_sendmsg_clicked()
{
    
    
    QString msg = ui->text_send->toPlainText();
    m_tcp->write(msg.toUtf8());
    ui->textEdit->append("服务器说:"+msg);
}

(5) close the connection

void MainWindow::on_bt_close_clicked()
{
    
    
    //主动和客户端断开连接
    if(NULL == m_tcp)
    {
    
    
        return;
    }
    m_tcp->disconnectFromHost();
    m_tcp->close();
    m_tcp = NULL;
}

(6) Trigger the above slot function. When the constructor uses connect()
when there is data transmission, the client QTcpSocket will trigger the readyRead() signal, and then readAll() reads the data and displays it.

connect(m_s,&QTcpServer::newConnection,this,[=]()
    {
    
    
        m_tcp = m_s->nextPendingConnection();
        ui->textEdit->append("成功和客户端建立了连接!");
        connect(m_tcp,&QTcpSocket::readyRead,this,[=]()
        {
    
    
            QByteArray data = m_tcp->readAll();
            ui->textEdit->append("客户端说:"+data);
        });
        connect(m_tcp,&QTcpSocket::disconnected,this,[=]()
        {
    
    
            ui->textEdit->append("客户端断开了连接!");
            m_tcp->close();
            m_tcp->deleteLater();
        });

    });

2. Implementation process of TCP client

Key points:
A. Call connectToHost to connect to the server

B. Call waitForConnected to determine whether the connection is successful

C. Connect the signal readyRead slot function to read data asynchronously

D. Call waitForReadyRead to block reading data

E. Call disconnected to disconnect

F. Call state() == QAbstractSocket::UnconnectedState and waitForDisconnected to determine whether to disconnect

(1) .h import header file

#include <QTcpSocket>

(2) Create a QTcpSocket socket

QTcpSocket *tcpsocket;//通信套接字

new in the constructor

tcpsocket = new QTcpSocket(this);

(3) Use this object to connect to the server

void MainWindow::on_bt_lianjie_clicked()
{
    
      
    qint16 port = ui->tcp_com->text().toInt();
    //unsigned short ip = ui->ip->text().toUShort();
    QString ip = ui->tcp_add->text();
    tcpsocket->connectToHost(QHostAddress(ip),port);
    if(tcpsocket->waitForConnected(3000))
    {
    
    
        ui->textdisplay->append("连接服务器成功!");
    }
    else
    {
    
    
        ui->textdisplay->append("连接失败,请检查IP地址和端口!");
    }
}

(4) send information write ()

void MainWindow::on_pushButton_clicked()
{
    
    
    QString msg = ui->text_send->toPlainText();
    ui->textdisplay->append("客户端说:"+msg);
    //获取编辑框内容
    QString str = ui->text_send->toPlainText();
    //发送数据
    tcpsocket->write(str.toUtf8().data());
    ui->textdisplay->append("客户端发送:"+str);
}

(5) Disconnect

void MainWindow::on_bt_duankai_clicked()
{
    
    
    //主动和对方断开连接
    tcpsocket->disconnectFromHost();
    tcpsocket->close();
    //断开成功
    if (tcpsocket->state() == QAbstractSocket::UnconnectedState || tcpsocket->waitForDisconnected(1000))
    {
    
    
        ui->textdisplay->append("连接已断开!");
    }
    else
    {
    
    
        ui->textdisplay->append("无法断开与服务器的连接!");
    }
}

(6) Trigger the above slot function, use connect() in the constructor, and
when new data arrives in the receiving buffer of the nested word socket of the client, the readRead() signal will be sent

connect(tcpsocket,&QTcpSocket::connected,this,[=]()
    {
    
    
        ui->textdisplay->append("成功和服务器建立连接!");
    });
    connect(tcpsocket,&QTcpSocket::readyRead,this,[=]()
    {
    
    
        QByteArray data = tcpsocket->readAll();
        ui->textdisplay->append("服务器说:"+data);
    });
    connect(tcpsocket,&QTcpSocket::disconnected,this,[=]()
    {
    
    
        //m_tcp->close();
        //m_tcp->deleteLater();
        ui->textdisplay->append("已和服务器断开连接!");
    });


insert image description here

Summarize

Tip: be good at summarizing, go further.

Guess you like

Origin blog.csdn.net/m0_51988927/article/details/124941676