zl程序教程

您现在的位置是:首页 >  工具

当前栏目

qt之TCP/IP通信客户端与服务器自动连接互相传输数据

2023-09-27 14:29:08 时间

一、前言

在开发上位机软件,用的最多的通信就是网络通信,串口通信和USB通信,串口通信相对是最容易的,USB通信在前面的文章中也专门写了一个博客介绍USB HID通信方式,见链接:https://blog.csdn.net/qq_37603131/article/details/100034701。本文主要介绍一下两个QT程序的TCP/IP通信,自动连接,互相发送数据通信方式。

二、环境

WIN8,QT5.7 Creator

三、正文

程序分为两份,一个是作为服务器,在程序启动后就建立一个所在电脑的本地服务器,一直在等待客户端去连接它,如未有连接,则一直等待,如连接成功,则向这个客户端发送数据,并且可接受客户端发出的数据进行处理。

另一个程序作为客户端,也是在程序启动后一直去启动主动连接服务器,这个可以手动设置连接哪一个ip或者在程序写好固定的ip,就让设备之前自动去连接,连接好就自动通讯。

下面就上核心代码:

服务器:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
bool connnectfalg=false;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //定时器配置
    timer = new QTimer(this);//创建1s定时器
    connect(timer, SIGNAL(timeout()), this, SLOT(timeSlot()));//绑定定时函数
    timer->start(100);
    //TCP/IP配置
    server = new QTcpServer();//开启服务端
    server->listen(QHostAddress::Any, 5000);//本地ip,端口号5000
    connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);//绑定新连接成功槽

}
MainWindow::~MainWindow()
{
    server->close();
    delete ui;
}
void MainWindow::timeSlot()
{
    if(connnectfalg)
        sendSingle();
}
//网络连接
void MainWindow::server_New_Connect()
{
    //获取客户端连接
    qDebug()<<"监听到网络连接";
    socket = server->nextPendingConnection();
    QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);//绑定接收到数据槽
    QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);//绑定断开连接槽
    connnectfalg=true;
    ui->label->setStyleSheet("image: url(:/PIC/1441292827_804185.png)");//连接成功,亮灯
}
//网络断开
void MainWindow::socket_Disconnected()
{
    qDebug() << "Disconnected!";
    connnectfalg=false;
    ui->label->setStyleSheet("image: url(:/PIC/1441292807_248395.png)");//连接断开,无灯
}

//发送信号
void MainWindow::sendSingle()
{
    QByteArray sd;
    for(int i=0;i<qrand()%100;i++)
        sd[i]=qrand();
    socket->write(sd);
    socket->flush();
}

//接收信号.
void MainWindow::socket_Read_Data()
{
    QByteArray buffer;
    static QByteArray allData;
    //读取缓冲区数据
    buffer = socket->readAll();
    if(!buffer.isEmpty())
    {
        allData+=buffer.toHex();
        comBatAnalyze(allData);
    }
}
//处理接收信号
void MainWindow:: comBatAnalyze(QByteArray &allData)
{
    QByteArray dataTemp;
    int t,len;
    int start;
    int move;
    unsigned char temp,temp2;

    bool ok;

    dataTemp=allData;

    qDebug()<<"dataTemp="<<dataTemp;

    dataTemp.clear();

    allData=dataTemp;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
#include <QTime>
#include <QApplication>
#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void socket_Read_Data();
    void socket_Disconnected();
    void timeSlot();
private:
    Ui::MainWindow *ui;
    QTcpSocket *socket;
    QTcpServer* server;
    QTimer *timer;
    void server_New_Connect();
    void sendSingle();
    void  comBatAnalyze(QByteArray &allData);
};

#endif // MAINWINDOW_H

客户端:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
bool connnectfalg=false;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    timer = new QTimer(this);//创建1s定时器
    connect(timer, SIGNAL(timeout()), this, SLOT(timeSlot()));//绑定定时函数
    timer->start(500);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::timeSlot()
{
    if(connnectfalg)//连接成功,一直发送数据,测试
        sendSingle();
    else//自动重新尝试连接
        on_pushButton_clicked();

}
//发送信号
void MainWindow::sendSingle()
{
    QByteArray sd;
    sd[0]=0xEF;
    sd[1]=0xFE;
    sd[2]=0xEF;
    socket->write(sd);
    socket->flush();
}
//连接网络
void MainWindow::on_pushButton_clicked()
{
     socket = new QTcpSocket();
     QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
     QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
     TcpConnect();
}
void MainWindow::TcpConnect()
{
    if(1)
    {
        QString IP;
        int port;
        IP =ui->lineEdit->text();
        port =5000;
        socket->abort();
        socket->connectToHost(IP, port);
        if(!socket->waitForConnected(1000))
        {
            qDebug() << "Connection failed!";
            return;
        }
        qDebug() << "Connect successfully!";
        ui->pushButton->setText("已连接");
        connnectfalg=true;
    }
    else
    {
        //断开连接
        socket->disconnectFromHost();
    }
}
//接收信号
void MainWindow::socket_Read_Data()
{
    QByteArray buffer;
    static QByteArray allData;
    //读取缓冲区数据
    buffer = socket->readAll();
    if(!buffer.isEmpty())
    {
        allData+=buffer.toHex();
        comBatAnalyze(allData);
    }
}
void MainWindow::socket_Disconnected()
{
    qDebug() << "Disconnected!";
    connnectfalg=false;
    ui->pushButton->setText("连接网络");
}
//处理接收信号
void MainWindow:: comBatAnalyze(QByteArray &allData)
{
    QByteArray dataTemp;
    int t,len;
    int start;
    int move;
    unsigned char temp,temp2;

    bool ok;

    dataTemp=allData;
    ui->textEdit->setText(dataTemp);
    qDebug()<<"dataTemp="<<dataTemp;
    dataTemp.clear();

    allData=dataTemp;
}

//手动发送数据
void MainWindow::on_pushButton_2_clicked()
{
    if(connnectfalg)
        sendSingle();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
#include <QTime>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void socket_Read_Data();
    void socket_Disconnected();
    void on_pushButton_clicked();
    void timeSlot();
    void on_pushButton_2_clicked();
private:
    Ui::MainWindow *ui;
    QTcpSocket *socket;
    QTcpServer* server;
    QTimer *timer;
    void TcpConnect();
    void sendSingle();
    void comBatAnalyze(QByteArray &allData);
};

#endif // MAINWINDOW_H

四、结语

通过以上连个程序就可以实现局域网内或者网络之前TCP/IP连接相互通信了。