Day26Qt implements QTcpServer-2022-01-06

Posted by hejgelato on Thu, 06 Jan 2022 13:50:10 +0100

Qt Network (I) tcp server

Introduction TCP

TCP protocol, transmission control protocol, is an underlying network protocol for data transmission. Many Internet protocols, including FTP and HTTP, are based on TCP protocol. TCP is a reliable transmission protocol for data flow and connection. QTcpSocket class provides an interface for TCP, which can be used to implement POP3, SMTP and other standard network protocols, as well as user-defined network protocols. One end of the connection is the client and the other end is the server, that is, the C/S model.

Steps and objectives

Using Qt network as a TCP server, you can receive access requests from clients and transmit data. First, create a QTcpServer class object to manage the server; Call the listen method to listen to the port corresponding to the corresponding address, so that the host can act as a server, so that the program can listen to the connection of a port; When a client sends a connection request, the server object will send a newConnection() signal. When there is an error in the listening process, the server will send an acceptError() signal; If an error occurs after the connection is established, the disconnected () signal will be sent, and the readyread () signal will be sent when there is data. When it is necessary to send data to the client, call the write method.

Summary and thinking

1. When using the network module, remember to add the network module to the pro file.
2. In practice, I encountered the situation that the connection was disconnected every time I clicked the send button. I inquired the answer in the network, but failed. Finally, it was determined that it was caused by the encryption software of the local computer. Therefore, when this problem occurs, close the firewall, anti-virus software and network related application processes, mostly from the perspective of local configuration.
3. Think about how to build a file server that can receive data uploaded by the client.
4. Use utf8 to send Chinese characters. If the other party also uses utf8, it can receive them correctly. The sending and receiving of Chinese characters are related to the coding method. QTextcodec can be used.

effect

The debugging results with the network interface assistant are as follows, and the received and received data are normal

The test results with Qt development client are as follows, and the Chinese characters are also sent and received normally,

code

ui file

main file

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

. h file

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpserver>
#include <QNetworkInterface>
#include <QTcpSocket>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void doProcessNewConnection();
    void doProcessAcceptError(QAbstractSocket::SocketError);
    void doProcessDisconnected();
    void doProcessReadyRead();
//    void doProcessConnect();
    void on_band_Btn_clicked();
    void on_tran_Btn_clicked();
private:
    Ui::MainWindow *ui;
    QTcpServer *myServer;
    QTcpSocket *client;
    QList<QTcpSocket *>arrayClient;
    void Init();
};
#endif // MAINWINDOW_H

. cpp file

#include "mainwindow.h"
#include "ui_mainwindow.h"

#define MAXNUM 100

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();
}

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

void MainWindow::Init()
{
    myServer = new QTcpServer(this);
    this->setWindowTitle("The server");
}
//Bind button slot function
void MainWindow::on_band_Btn_clicked()
{
   
    //Method 1: traverse the network card ip through the program
//    QList<QHostAddress>addrs = QNetworkInterface::allAddresses();
//    for (int i = 0; i <addrs.length(); ++i) {
//        QHostAddress addr = addrs.at(i);
//        qDebug()<<addr.toString();
//        if(addr.toString().contains("192.")){
//            myAddr = addr.toString();
//            break;
//        }
//    }
    //Method 2: manually set ip
    QString myAddr = ui->serverIP->text();
    QString myPort = ui->serverPort->text();
    QString msg;
    bool ret = myServer->listen(QHostAddress(myAddr),myPort.toUInt());//Listen to the corresponding port of the corresponding address to make the host as a server
    if(!ret){
        msg = "Binding failed!";
    }
    else{
        msg = "Binding succeeded!";
        ui->band_Btn->setEnabled(false);
    }
    ui->textEdit->append(msg);

    myServer->setMaxPendingConnections(MAXNUM);//Set the maximum number of waiting connections in the queue. The default is 30
    connect(myServer,SIGNAL(newConnection()),this,SLOT(doProcessNewConnection()));//After listening, the new client access will trigger this signal
    connect(myServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
            this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));//If there is an error in the listening process, it will enter this slot

}
//Bind send button slot function
void MainWindow::on_tran_Btn_clicked()
{
    //Obtain interface ip address and port information
    QString ip = ui->clientIP->text();
    QString port = ui->clientPort->text();
    //Find the corresponding customer
    for (int i = 0; i < arrayClient.length(); ++i) {
        if(arrayClient.at(i)->peerAddress().toString() == ip){//Find the corresponding ip address
            if(arrayClient.at(i)->peerPort() == port.toUInt()){//Find the corresponding port
                QString msg = ui->textEdit_2->toPlainText();
                arrayClient.at(i)->write(msg.toUtf8());//Use utf8 to send Chinese characters, and the other party can receive them correctly
                ui->textEdit_2->clear();
                break;
            }
        }
    }
}
void MainWindow::doProcessNewConnection()
{
  client =  myServer->nextPendingConnection();//Establish a connection and get the client object
  QString msg = QString("client[%1:%2] Join in!").arg(client->peerAddress().toString()).arg(client->peerPort());
  ui->textEdit->append(msg);
  arrayClient.append(client);//Store connected clients
  //Client disconnect
connect(client,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));//After establishing indirection, monitor the disconnection signal
  //Read content
  connect(client,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));//Ready to receive data
}
void MainWindow::doProcessAcceptError(QAbstractSocket::SocketError err)
{
    qDebug()<<err;
}
void MainWindow::doProcessDisconnected()
{
    QTcpSocket *client = (QTcpSocket *)this->sender();
    QString msg = QString("client[%1:%2] sign out!").arg(client->peerAddress().toString()).arg(client->peerPort());
    ui->textEdit->append(msg);
    //Delete client list disconnected clients
    for (int i = 0; i < arrayClient.length(); ++i) {
        if(arrayClient.at(i)->peerAddress() == client->peerAddress()){
            if(arrayClient.at(i)->peerPort() == client->peerPort()){
                arrayClient.removeAt(i);
            }
        }
    }
}
void MainWindow::doProcessReadyRead()
{
    QTcpSocket *client = (QTcpSocket *)this->sender();
    QString str1 = QString("client[%1:%2] Say:").arg(client->peerAddress().toString()).arg(client->peerPort());//Returns the ip and port of the client
    QString msg;
    QString str2;
    while(!client->atEnd()){
        msg.append(QString(client->readAll()));//receive data 
    }
    str2 = QString("%1%2").arg(str1).arg(msg);
    ui->textEdit->append(str2);
}

Topics: network Qt server TCP/IP