Qt_C++ RFID网络读卡器Socket Udp通讯示例源码

news2024/11/24 11:33:18

本示例使用的设备: WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QStringList>
#include <QUdpSocket>
#include <QException>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class Setnetpara; // 前向声明

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void sockinit();        //初始化Socket Udp
    void listadditems(int ctr,QString listinfo);  //显示通读报文
    void read_data();       //UDP端口接收数据
    void DisableSendAgain(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);  //确认接收到数据
    void Analyze_c1(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //解析读取M1卡卡号
    void Analyze_c3(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //主动读取M1卡扇区数据的返回
    void Analyze_c5(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //指定区号密钥读取M1卡扇区数据
    void Analyze_cd(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //指定区号密钥写数据到M1卡扇区的返回
    void Analyze_d1(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //解析读取ID卡卡号
    void Analyze_cf_df(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);     //解析IC、ID卡离开读卡器
    void Analyze_f2(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //解析设备开机、响应搜索指令的返回
    void Analyze_f6(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //响应查询设备型号固件日期指令的返回
    void Analyze_a4(QHostAddress ip,quint16 port,unsigned char buf[], qint64 len);        //查询wifi连接状态

    void Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber);  //接收到设备信息立即回应
    void SendBuffAct();

    void on_PBSearch_clicked();

    void on_CBIP_currentIndexChanged(int index);

    void on_PBClear_clicked();

    void on_tableWidget_cellClicked(int row, int column);

    void on_PBEditpara_clicked();

    void on_PBSendDispBeep_clicked();

    void on_PBbeep_clicked();

    void on_PBSwitchOn_clicked();

    void on_PBSwitchOff_clicked();

    void on_PBSendDispTTS_clicked();

    void on_PBSendDispSpk_clicked();

    void on_PBReadCard_clicked();

    void on_PBWriteCard_clicked();

    void on_PBChangeKey_clicked();

    void on_PBSetRW_clicked();

    void on_PBcopylist_clicked();

    void on_pushButton_9_clicked();

    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_7_clicked();

    void on_pushButton_8_clicked();

    void on_pushButton_SetTCP_clicked();

    void on_pushButton_SetHttp_clicked();

    void on_pushButton_16_clicked();

    void on_PBClear_2_clicked();

    void on_radioButton_IP_toggled(bool checked);

    void on_pushButton_SetUp_clicked();

    void on_pushButton_Read_clicked();

private:
    Ui::MainWindow *ui;
    QUdpSocket * udpSocket;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "QMessageBox"
#include <QUdpSocket>
#include <exception>
#include <QByteArray>
#include <QString>
#include <string>
#include <QTime>
#include <QStringList>
#include <QClipboard>


bool listening=false;               //sock侦听标志
QByteArray sendData;                //发送数据缓冲
unsigned char readcardbuf[1024];    //接收M1卡扇区数据缓冲

 //获取本机所有网卡IP------------------------------------------------------------------------------------------------------
QStringList getAllIPAddresses() {
    QStringList ips;
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    for (int i = 0; i < list.size(); ++i) {
        QHostAddress address = list.at(i);
        // 检查是否为IPv4地址,并排除回环地址
        if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress::LocalHost) {
            ips << address.toString();
        }
    }
    return ips;
}

//判断IP地址是否合法---------------------------------------------------------------------------------------------------------
bool isValidIP(const QString &ip) {
    QHostAddress address(ip);
    return address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol;
}

//判断是否有效MAC------------------------------------------------------------------------------------------------------------
bool isValidMac(const QString &mac) {
   try
    {
        QStringList liststr = mac.split("-");
        for (int i=0 ;i<6;i++){
           bool ok;
           quint8 macb =liststr[i].toInt(&ok,16);
           if (!ok){return false;}
         }
        return true;
    }
   catch (QException& e) {
        return false;
    }
}

//根据IP地址获取MAC----------------------------------------------------------------------------------------------------------
QString getMacByIp(const QString &ip) {
    QHostInfo info = QHostInfo::fromName(ip);
    foreach (const QHostAddress &address, info.addresses()) {
        if (address.protocol() == QAbstractSocket::IPv4Protocol) {
            foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
                if (interface.flags().testFlag(QNetworkInterface::IsUp) && interface.flags().testFlag(QNetworkInterface::IsRunning)) {
                    foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
                        if (entry.ip() == address) {
                            return interface.hardwareAddress();
                        }
                    }
                }
            }
        }
    }
    return QString();
}

//获取系统现时间-------------------------------------------------------------------------------------------------------------
QString getsystime(){
    QTime time = QTime::currentTime();
    QString timeStr = time.toString("hh:mm:ss.zzz");
    return timeStr;
}

//获取系统日期时间-------------------------------------------------------------------------------------------------------------
QString getsysdatetime(){
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString dateTimeString = currentDateTime.toString("yy-MM-dd hh:mm:ss");
    return dateTimeString;
}

//QByteArray转16进制QString------------------------------------------------------------------------------------------------
QString ByteArrayToHexString(QByteArray data){
    QString ret(data.toHex().toUpper());
    int len = ret.length()/2;
    for(int i=1;i<len;i++)
    {
        ret.insert(2*i+i-1," ");
    }
    return ret;
}

//检测输入数据是否为16进制数,将正确的16进制字符存入数组,并返回长度--------------------------------------------------------------------
static int checkhexdata(QString inputstr,unsigned char *databuf){
    QChar ch;
    QString writinf = inputstr.trimmed();
    QString writinf1 = "";
    int m = 0;
    int n = 0;
    char s;

    if(writinf.length()<1){
        return -1;
    }

    ch = writinf.at(0);
    s = writinf.at(0).toLatin1();
    for(int i=0; i<writinf.length() ; i++)
    {
        ch = writinf.at(i);
        s = writinf.at(i).toLatin1();
        if((('0' <= s) && (s <= '9')) || (('A' <= s) && (s <= 'F')) || (('a' <= s) && (s <= 'f')))
        {
            writinf1 += ch;
            n++;
            if(n==2){
                bool ok;
                databuf[m++] = writinf1.toInt(&ok,16);
                writinf1 = "";
                n = 0;
            }
        }
        else if(s == ' '){

        }
    }
    return m;
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{    
    ui->setupUi(this);
    ui->TEPort->setPlainText("39169");        //出厂默认39169端口
    ui->textEdit_remoiport->setText("255.255.255.255:39169");
    ui->textEdit_DeviceNumber->setText("00000");
    ui->textEdit_tts->setText("欢迎您使用我们的网络读卡器!");
    ui->textEdit_disp->setText("欢迎您使用我们的网络读卡器!");
    ui->spinBox_dispdelay->setValue(5);
    ui->spinBox_swit->setValue(30);
    ui->spinBox_voice->setValue(8);
    ui->textEdit_M1UID->setText("00000000");
    ui->textEdit_authkey->setText("FFFFFFFFFFFF");
    ui->textEdit_newkey->setText("FF FF FF FF FF FF FF 07 80 69 FF FF FF FF FF FF");
    ui->scrollArea->setVisible(false);    
    ui->scrollArea->move(180,40);
    ui->scrollArea_wifi->setVisible(false);
    ui->scrollArea_wifi->move(250,130);
    ui->groupBox_dhcp->setVisible(false);

    QStringList ips = getAllIPAddresses();    
    foreach (QString ip, ips) {
        ui->CBIP->addItem(ip);
    }
    if(ui->CBIP->count()<1){
        QMessageBox::information(NULL, "提示", "未搜索到本机的网卡,系统不能正常运行!");
        delete ui;
    }
    sockinit();
}

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

//通讯报文显示-----------------------------------------------------------------------------------------------------
void MainWindow::listadditems(int ctr,QString listinfo){
    switch (ctr){
    case 0:
        if(ui->listWidget->count()>10){
            ui->listWidget->clear();
        }
        ui->listWidget->addItem(listinfo);
        ui->listWidget->setCurrentRow(ui->listWidget->count()-1);
        break;
    case 1:
        ui->textEdit_msg->setText(listinfo);
    }
}

//广播发送搜索所有在线的设备-------------------------------------------------------------------------------------------
void MainWindow::on_PBSearch_clicked()
{
    int n = ui->tableWidget->rowCount();//总行数
    for (int i = 0;i <= n;i++)
        ui->tableWidget->removeRow(0);//遍历删除第0行


    QHostAddress broadcastAddress("255.255.255.255");
    quint16 port1 = 39169;
    sendData.clear();
    sendData.append(0xA6);
    udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);        //搜索所有在线设备
    QString  dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22)+"A6" ;
    listadditems(0,dispinf);

    sendData.clear();
    sendData.append(0xA8);
    udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);      //查询在线设备型号、固件日期
    dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22)+"A8" ;
    listadditems(0,dispinf);
}

void MainWindow::sockinit(){    //初始化Socket UDP侦听端口
    try{
        if(!listening){
            QString ipstr=ui->CBIP->currentText();
            QHostAddress localeip(ipstr);
            quint16 port=ui->TEPort->toPlainText().toUInt();
            udpSocket =new QUdpSocket(this);
            udpSocket->bind(localeip,port);                         //udpSocket->bind(QHostAddress::Any,port);  这个方式是绑定所有网卡,这样发不出广播包
            connect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data);
            listening=true;
            listadditems(0,getsystime()+" Sock已启动侦听"+ipstr+":"+ui->TEPort->toPlainText());
        }
    }
    catch(_exception)
    {
        listening=false;
        udpSocket->close();
        listadditems(0,getsystime()+" Sock侦听已关闭!");
    }
}

//Socket UDP端口接收数据---------------------------------------------------------------------------------------------------------
void MainWindow::read_data(){
    unsigned char databuff[1024] = {0};
    QHostAddress ip;
    quint16 port;
    qint64 buflen = udpSocket->readDatagram((char *)databuff, sizeof(databuff), &ip, &port);
    QString str;
    for (int i = 0; i < buflen; i++)
    {
        str +=QString::asprintf("%02X ", databuff[i]);
    }    
    QString  dispinf=getsystime()+" Receive: "+(ip.toString()+":"+QString::number(port)+"             ").mid(0,22)+str ;
    listadditems(0,dispinf);

    switch (databuff[0]){
    case 0xc1:
        Analyze_c1(ip, port,databuff,buflen);          //解析读取IC卡卡号
        break;

    case 0xc3:
        Analyze_c3(ip, port,databuff,buflen);          //主动读取M1卡扇区数据的返回
        break;

    case 0xc5:
        Analyze_c5(ip, port,databuff,buflen);          //指定区号密钥读取M1扇区数据返回
        break;

    case 0xcd:
        Analyze_cd(ip, port,databuff,buflen);          //指定区号密钥写数据到M1卡扇区返回
        break;

    case 0xd1:
        Analyze_d1(ip, port,databuff,buflen);          //解析读取ID卡卡号
        break;

    case 0xcf:
    case 0xdf:
        Analyze_cf_df(ip, port,databuff,buflen);       //解析IC、ID卡离开读卡器
        break;

    case 0xf2:
        Analyze_f2(ip, port,databuff,buflen);          //在线设备响应搜索指令的返回、读卡器上电开机上传设备信息
        break;

    case 0xf6:
        Analyze_f6(ip, port,databuff,buflen);          //在线设备响应查询型号、固件日期指令的返回
        break;

    case 0xa4:
        Analyze_a4(ip, port,databuff,buflen);          //查询WIFI叁数的返回
        break;

    default:
        break;
    }
}

//确认接收到的信息----------------------------------------------------------------------------------------------------------------
void MainWindow::DisableSendAgain(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString SendHex=getsystime()+" Send To: "+(ip.toString()+":"+QString::number(port)+"             ").mid(0,22)+"69 " ;
    sendData.clear();
    sendData.append(0x69);
    for (int i=1;i<9;i++){
        sendData.append(databuff[i]);
        SendHex=SendHex+QString::asprintf("%02X ", databuff[i]);
    }
    udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress(ip), port);    
    listadditems(0,SendHex+"      确定接收,不要再次发送此帧数据啦...");
}

//解析读取IC卡卡号-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次

    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
    QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号
    QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X", databuff[10],databuff[11],databuff[12],databuff[13]);  //16进制卡号正码
    QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[13],databuff[12],databuff[11],databuff[10]);  //16进制卡号反码
    bool status;
    QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //转8H10D反码卡号
    QString SerialNumber="";        //设备全球唯一硬件序号
    for (int i=14;i<buflen;i++){
        SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);
    }
    QString  DispInf="读取M1卡号,设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;
    listadditems(1,DispInf);
    ui->textEdit_M1UID->setText(CardnoHexZ);

    if(ui->checkBox_Resp->isChecked()){Respondinfo(getsysdatetime()+"卡号:"+Cardno8H10D,ip,port,DeviceNumber);}  //回应驱动设备显示+蜂鸣响声
}

//主动读取扇区数据的返回--------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c3(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
    QString CardnoHex="";
    for (int i=12;i<16;i++){
        CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]);
    }

    int j=databuff[10]*48;
    int m=databuff[11]*48;
    for(int i=0;i<m;i++){
        readcardbuf[j+1]=databuff[16+i];
    }

    if((databuff[10]+databuff[11])>=databuff[9]){
        m=databuff[9]*48;
        QString DataHex="";
        for (int i=0;i<m;i++){
            DataHex=DataHex+QString::asprintf("%02X ",readcardbuf[i]);
        }
        ui->textEdit_data->setPlainText(DataHex);
        QString DispInf="读取M1卡扇区数据成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex;
        listadditems(1,DispInf);
        ui->textEdit_M1UID->setText(CardnoHex);

        if(ui->checkBox_Resp->isChecked()){Respondinfo(getsysdatetime()+"卡号:"+CardnoHex,ip,port,DeviceNumber);}  //回应驱动设备显示+蜂鸣响声
    }
}

//指定区号密钥读取M1扇区数据返回-----------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c5(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
    QString CardnoHex="";    
    QString  DispInf="";
    for (int i=8;i<12;i++){
        CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]);
    }
    QString Sector=QString::asprintf("%d", databuff[12]);    //扇区号

    DispInf="读取M1卡"+Sector+"扇区数据";
    switch (databuff[13]){
    case 0:
        {
            QString DataHex="";
            for (int i=0;i<48;i++){
                DataHex=DataHex+QString::asprintf("%02X ", databuff[i]);
            }
            DispInf=DispInf+"成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex;
            ui->textEdit_data->setPlainText(DataHex);
            break;
        }
    case 8:
            DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",没有卡片在感应区!";
            break;
    case 12:
            DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex+",卡密码认证失败!";
            break;
    default:
            DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",错误代码:"+QString::asprintf("%d", databuff[13]);
            break;
    }
    listadditems(1,DispInf);
    ui->textEdit_M1UID->setText(CardnoHex);

    if(ui->checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);}  //回应驱动设备显示+蜂鸣响声
}

//指定区号密钥写数据到M1卡扇区返回状态---------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_cd(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString IPAddress=QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4])+"."+QString::asprintf("%d", databuff[5]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    QString DeviceNumber=QString::asprintf("%05d",databuff[6]+databuff[7]*256);   //设备自编机号
    QString CardnoHex="";
    for (int i=9;i<13;i++){
        CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); //16进制卡号
    }
    QString Sector=QString::asprintf("%d", databuff[13]);           //扇区号
    QString Pages=QString::asprintf("%d", databuff[8]);             //本次操作的扇区总数
    QString  DispInf="";
    if(databuff[1]==0x3a){
        DispInf="修改M1卡"+Sector+"扇区密钥";
    }else if(databuff[1]==0x3d){
        DispInf="写数据到M1卡"+Sector+"扇区";
    }
    switch (databuff[14]){
    case 0:
            DispInf=DispInf+"成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex;
            break;
    case 8:
            DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",没有卡片在感应区!";
            break;
    case 12:
            DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex+",卡密码认证失败!";
            break;
    default:
            DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",错误代码:"+QString::asprintf("%d", databuff[13]);
            break;
    }
    listadditems(1,DispInf);
    if(ui->checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);}  //回应驱动设备显示+蜂鸣响声
}

//解析读取ID卡卡号-----------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_d1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次

    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
    QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号
    QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X%02X", databuff[9],databuff[10],databuff[11],databuff[12],databuff[13]);  //16进制卡号正码,databuff[13]为厂商代码
    QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[12],databuff[11],databuff[10],databuff[9]);   //16进制卡号反码,databuff[13]为厂商代码
    bool status;
    QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //转8H10D反码卡号
    QString SerialNumber="";        //设备全球唯一硬件序号
    for (int i=14;i<buflen;i++){
        SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);
    }
    QString  DispInf="读取ID卡号,设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;
    listadditems(1,DispInf);
    if(ui->checkBox_Resp->isChecked()){Respondinfo(getsysdatetime()+"卡号:"+Cardno8H10D,ip,port,DeviceNumber);}  //回应驱动设备显示+蜂鸣响声
}

//解析IC\ID卡离开读卡器-----------------------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_cf_df(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次

    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
    QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号
    int infotype=databuff[9];           //数据说明,1表示只读取UID卡号
    int cardnolen=databuff[10];         //UID卡号长度
    QString CardnoHexZ="";              //16进制卡号正码
    for (int i=0;i<cardnolen;i++){
        CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[11+i]);
    }
    QString CardnoHexF=CardnoHexZ.mid(6,2)+CardnoHexZ.mid(4,2)+CardnoHexZ.mid(2,2)+CardnoHexZ.mid(0,2);   //16进制卡号反码
    bool status;
    QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //转8H10D反码卡号
    QString SerialNumber="";        //设备全球唯一硬件序号
    for (int i=11+cardnolen;i<buflen;i++){
        SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);
    }
    QString  DispInf="";
    if(databuff[0]==0xcf){DispInf="M1卡离开读卡器,";}else{DispInf="ID卡离开读卡器,";}
    DispInf=DispInf+"设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;
    listadditems(1,DispInf);
}

//在线设备响应搜索指令的返回、读卡器上电开机上传设备信息-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_f2(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]);  //设备IP
    QString mask=QString::asprintf("%d", databuff[5])+"."+QString::asprintf("%d", databuff[6])+"."+QString::asprintf("%d", databuff[7])+"."+QString::asprintf("%d", databuff[8]);       //设备掩码
    QString PortStr=QString::asprintf("%05d",databuff[9]+databuff[10]*256);         //通讯端口
    QString DeviceNumber=QString::asprintf("%05d",databuff[11]+databuff[12]*256);   //设备自编机号
    QString GetWay=QString::asprintf("%d", databuff[13])+"."+QString::asprintf("%d", databuff[14])+"."+QString::asprintf("%d", databuff[15])+"."+QString::asprintf("%d", databuff[16]); //设备网关
    QString GetWayMAC=QString::asprintf("%02X", databuff[17])+"-"+QString::asprintf("%02X", databuff[18])+"-"+QString::asprintf("%02X", databuff[19])+"-"+QString::asprintf("%02X", databuff[20])+"-"+QString::asprintf("%02X", databuff[21])+"-"+QString::asprintf("%02X", databuff[22]); //设备网关MAC
    QString ServerIp=QString::asprintf("%d", databuff[23])+"."+QString::asprintf("%d", databuff[24])+"."+QString::asprintf("%d", databuff[25])+"."+QString::asprintf("%d", databuff[26]);  //远程服务器IP
    QString ServerMAC=QString::asprintf("%02X", databuff[27])+"-"+QString::asprintf("%02X", databuff[28])+"-"+QString::asprintf("%02X", databuff[29])+"-"+QString::asprintf("%02X", databuff[30])+"-"+QString::asprintf("%02X", databuff[31])+"-"+QString::asprintf("%02X", databuff[32]); //远程服务器MAC
    QString MACPara=QString::asprintf("%d", databuff[33]);    //MAC获取方式
    QString NetPara=QString::asprintf("%d", databuff[34]);    //设备参数
    QString ModuleNumber=QString::asprintf("%d", databuff[35])+"-"+QString::asprintf("%d", databuff[36])+"-"+QString::asprintf("%d", databuff[37])+"-"+QString::asprintf("%d", databuff[38]);       //网络模块编号
    QString STMAC="16-88-"+QString::asprintf("%02X", databuff[35])+"-"+QString::asprintf("%02X", databuff[36])+"-"+QString::asprintf("%02X", databuff[37])+"-"+QString::asprintf("%02X", databuff[38]);  //STC版设备MAC
    QString CHMAC="";          //CH系列设备MAC
    QString SerialNumber="";   //唯一设备硬件序号
    for (int i=39;i<buflen;i++){
        SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);
        if (i<45){
            CHMAC=QString::asprintf("%02X", databuff[i])+CHMAC;
            if(i<44){CHMAC="-"+CHMAC;}
        }
    }

    int row = 0;
    ui->tableWidget->insertRow(row);
    QTableWidgetItem* item = new QTableWidgetItem;
    item->setText(DeviceNumber);
    ui->tableWidget->setItem(row,0, item);

    item = new QTableWidgetItem;
    item->setText(IPAddress);
    ui->tableWidget->setItem(row,1, item);

    item = new QTableWidgetItem;
    item->setText(mask);
    ui->tableWidget->setItem(row,2, item);

    item = new QTableWidgetItem;
    item->setText(PortStr);
    ui->tableWidget->setItem(row,3, item);

    item = new QTableWidgetItem;
    item->setText(GetWay);
    ui->tableWidget->setItem(row,4, item);

    item = new QTableWidgetItem;
    item->setText(GetWayMAC);
    ui->tableWidget->setItem(row,5, item);

    item = new QTableWidgetItem;
    item->setText(ServerIp);
    ui->tableWidget->setItem(row,6, item);

    item = new QTableWidgetItem;
    item->setText(ServerMAC);
    ui->tableWidget->setItem(row,7, item);

    item = new QTableWidgetItem;
    item->setText(MACPara);
    ui->tableWidget->setItem(row,8, item);

    item = new QTableWidgetItem;
    item->setText(NetPara);
    ui->tableWidget->setItem(row,9, item);

    item = new QTableWidgetItem;
    item->setText(ModuleNumber);
    ui->tableWidget->setItem(row,10, item);

    item = new QTableWidgetItem;
    item->setText(STMAC);
    ui->tableWidget->setItem(row,11, item);

    item = new QTableWidgetItem;
    item->setText(SerialNumber);
    ui->tableWidget->setItem(row,12, item);

    item = new QTableWidgetItem;
    item->setText(CHMAC);
    ui->tableWidget->setItem(row,13, item);

    for (int i=0;i<=13;i++){
        ui->tableWidget->resizeColumnToContents(i); //自动列宽
    }
}

//响应查询设备型号固件日期指令的返回---------------------------------------------------------------------------------------------------
void MainWindow::Analyze_f6(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]);  //设备IP
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //设备自编机号
    int NameLen=databuff[7];    //设备型号名称长度
    QByteArray namebuf;         //设备型号
    for (int i=0;i<NameLen;i++){
        namebuf.append(databuff[8+i]);
    }
    QString namestr=namebuf;

    int VersionDateLen=databuff[8 + NameLen];  //固件日期长度
    QByteArray verbuf;   //固件日期
    for (int i=0;i<VersionDateLen;i++){
        verbuf.append(databuff[8 + NameLen + 1+i]);
    }
    QString verdatestr=verbuf;

    int rowCount = ui->tableWidget->rowCount();
    for (int row = 0; row < rowCount; ++row) {
         QTableWidgetItem *item = ui->tableWidget->item(row, 1);
         QString ipstr = item->text();
         if (IPAddress==ipstr){
            item = new QTableWidgetItem;
            item->setText(namestr);
            ui->tableWidget->setItem(row,14, item);
            ui->tableWidget->resizeColumnToContents(14); //自动列宽

            item = new QTableWidgetItem;
            item->setText(verdatestr);
            ui->tableWidget->setItem(row,15, item);
            ui->tableWidget->resizeColumnToContents(15); //自动列宽
            return;
         }
    }
}

//查询wifi连接状态---------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_a4(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString IPAddress=QString::asprintf("%d", databuff[7])+"."+QString::asprintf("%d", databuff[8])+"."+QString::asprintf("%d", databuff[9])+"."+QString::asprintf("%d", databuff[10]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应
    ui->listWidget_wifi->addItem("WIFI的IP地址:"+IPAddress);
    QString mask=QString::asprintf("%d", databuff[11])+"."+QString::asprintf("%d", databuff[12])+"."+QString::asprintf("%d", databuff[13])+"."+QString::asprintf("%d", databuff[14]);       //设备掩码
    ui->listWidget_wifi->addItem("WIFI子网掩码:"+mask);
    QString MACStr=QString::asprintf("%02X", databuff[15])+"-"+QString::asprintf("%02X", databuff[16])+"-"+QString::asprintf("%02X", databuff[17])+"-"+QString::asprintf("%02X", databuff[18])+"-"+QString::asprintf("%02X", databuff[19])+"-"+QString::asprintf("%02X", databuff[20]); //MAC地址
    ui->listWidget_wifi->addItem("WIFI_MAC地址:"+MACStr);
    QString GateWay=QString::asprintf("%d", databuff[21])+"."+QString::asprintf("%d", databuff[22])+"."+QString::asprintf("%d", databuff[23])+"."+QString::asprintf("%d", databuff[24]); //设备网关
    ui->listWidget_wifi->addItem("WIFI网关地址:"+GateWay);
    QString GatewayMAC=QString::asprintf("%02X", databuff[25])+"-"+QString::asprintf("%02X", databuff[26])+"-"+QString::asprintf("%02X", databuff[27])+"-"+QString::asprintf("%02X", databuff[28])+"-"+QString::asprintf("%02X", databuff[29])+"-"+QString::asprintf("%02X", databuff[30]); //网关MAC
    ui->listWidget_wifi->addItem("网关 MAC地址:"+GatewayMAC);
    switch (databuff[31]){
    case 0:
        ui->listWidget_wifi->addItem("WIFI网络状态:已连接wifi");
        break;
    case 1:
        ui->listWidget_wifi->addItem("WIFI网络状态:连接失败!");
        break;
    case 2:
        ui->listWidget_wifi->addItem("WIFI网络状态:已初始化!");
        break;
    default:
        ui->listWidget_wifi->addItem("WIFI网络状态:未初始化!");
        break;
    }
    QByteArray devname;
    for(int i=0 ;i<databuff[32];i++){
        devname.append(databuff[34+i]);
    }
    QString devnamestr=devname;
    ui->listWidget_wifi->addItem("读卡器  名称:"+devnamestr);

    QByteArray wifname;
     for(int i=0 ;i<databuff[33];i++){
         wifname.append(databuff[44+i]);
     }
     QString wifinamestr=wifname;
     ui->listWidget_wifi->addItem("WIFI热点名称:"+wifinamestr);
}

//更换不同的网卡----------------------------------------------------------------------------------------------------
void MainWindow::on_CBIP_currentIndexChanged(int index)
{
    if (listening){
        disconnect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data);
        udpSocket->close();
        listening=false;
        listadditems(0,getsystime()+" Sock侦听已关闭!");
    }
    sockinit();
}


void MainWindow::on_PBClear_clicked()
{
    ui->listWidget->clear();
    ui->textEdit_msg->setText("");
}

//在在线设备列表中选取一台设备IP端口
void MainWindow::on_tableWidget_cellClicked(int row, int column)
{
    int currentRow = ui->tableWidget->currentIndex().row();
    QString DeviceNumber = ui->tableWidget->item(currentRow,0)->text();
    QString IPAddress= ui->tableWidget->item(currentRow,1)->text();
    QString PortStr= ui->tableWidget->item(currentRow,3)->text();
    ui->textEdit_DeviceNumber->setText(DeviceNumber);
    ui->textEdit_remoiport->setText(IPAddress+":"+PortStr);

    ui->New_Nember->setText(DeviceNumber);
    ui->New_IP->setText(IPAddress);
    ui->New_ServerIP->setText( ui->tableWidget->item(currentRow,6)->text());
    ui->ServerMAC->setText( ui->tableWidget->item(currentRow,7)->text());
    ui->New_Mask->setText( ui->tableWidget->item(currentRow,2)->text());
    ui->New_Gateway->setText( ui->tableWidget->item(currentRow,4)->text());
    ui->GateWayMac->setText( ui->tableWidget->item(currentRow,5)->text());
    ui->New_Port->setText( ui->tableWidget->item(currentRow,3)->text());
    ui->Serial_Number->setText( ui->tableWidget->item(currentRow,10)->text());

    quint8 functionid=ui->tableWidget->item(currentRow,9)->text().toInt();
    if((functionid % 2)>0){ui->checkBox_beep->setChecked(true);}else{ui->checkBox_beep->setChecked(false);}
    functionid=functionid/2;
    if((functionid % 2)>0){ui->checkBox_dhcp->setChecked(true);}else{ui->checkBox_dhcp->setChecked(false);}
    functionid=functionid/2;
    ui->comboBox_out->setCurrentIndex(functionid % 2);
    functionid=functionid/2;
    functionid=functionid % 8;
    if (functionid<=4){ui->comboBox_in->setCurrentIndex(functionid);}else{ui->comboBox_in->setCurrentIndex(0);}

    quint8 automac=ui->tableWidget->item(currentRow,8)->text().toInt();
    switch (automac){
    case 0:
        ui->radioButton1->setChecked(false);
        ui->radioButton2->setChecked(true);
        ui->radioButton3->setChecked(false);
        ui->radioButton4->setChecked(true);
        break;
    case 1:
        ui->radioButton1->setChecked(true);
        ui->radioButton2->setChecked(false);
        ui->radioButton3->setChecked(false);
        ui->radioButton4->setChecked(true);
        break;
    case 2:
        ui->radioButton1->setChecked(false);
        ui->radioButton2->setChecked(true);
        ui->radioButton3->setChecked(true);
        ui->radioButton4->setChecked(false);
        break;
    default:
        ui->radioButton1->setChecked(true);
        ui->radioButton2->setChecked(false);
        ui->radioButton3->setChecked(true);
        ui->radioButton4->setChecked(false);
        break;
    }
}


void MainWindow::on_PBEditpara_clicked()
{
    int currentRow = ui->tableWidget->currentIndex().row();
    if (currentRow<0){
        QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);
    }else{
        ui->scrollArea_wifi->setVisible(false);
        ui->scrollArea->setVisible(true);
    }
}

//将sendData缓冲数据发送到指定的设备IP端口---------------------------------------------------------------------------------------
void MainWindow:: SendBuffAct()
{
    QString RemoIPort=ui->textEdit_remoiport->toPlainText();
    QStringList liststr = RemoIPort.split(":");
    QHostAddress Remoip(liststr[0]);
    quint16 Remoport=liststr[1].toUInt();

    udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress(Remoip), Remoport);

    QString SendHex=getsystime()+" Send To: "+(Remoip.toString()+":"+QString::asprintf("%d",Remoport)+"             ").mid(0,22);
    SendHex=SendHex+ByteArrayToHexString(sendData);
    listadditems(0,SendHex);
}

//驱动设备蜂鸣响声+文字显示-------------------------------------------------------------------------------------------------
void MainWindow::on_PBSendDispBeep_clicked()
{
    sendData.clear();
    sendData.append(0x5A);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码,255表示不响声
    sendData.append(ui->spinBox_dispdelay->value());   //文字显示时长,
    QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是为了确保满屏34位显示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;i<34;i++){
        sendData.append(Dispbyte[i]);
    }
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//驱动设备蜂鸣响声-----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBbeep_clicked()
{
    sendData.clear();
    sendData.append(0x96);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//驱动设备开启继电器----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBSwitchOn_clicked()
{
    sendData.clear();
    sendData.append(0x78);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());
    bool status;
    sendData.append(swithno.toUInt(&status,16));       //选择继电器
    quint16 deltime=ui->spinBox_swit->value();
    sendData.append(deltime % 256);                    //开启延时低位
    sendData.append(deltime / 256);                    //开启延时高位

    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//驱动设备关闭继电器----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBSwitchOff_clicked()
{
    sendData.clear();
    sendData.append(0x78);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    QString swithno="E"+QString::asprintf("%d",ui->CBSwitch->currentIndex());
    bool status;
    sendData.append(swithno.toUInt(&status,16));       //选择继电器
    quint16 deltime=ui->spinBox_swit->value();
    sendData.append(deltime % 256);                    //延时低位
    sendData.append(deltime / 256);                    //延时高位

    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//驱动设备显示文字+蜂鸣响声+播报TTS语音+开启继电器开关------------------------------------------------------------------------------
void MainWindow::on_PBSendDispTTS_clicked()
{
    if(ui->spinBox_voice->value()>16){ui->spinBox_voice->setValue(16);} //tts最大语音取值16
    QString strls="[v"+QString::asprintf("%d",ui->spinBox_voice->value())+"]";
    strls=strls+ui->textEdit_tts->toPlainText().trimmed();
    QByteArray SpeakArr=strls.toLocal8Bit();         //TS语音转换为Ansi码
    quint8 speakbytes=SpeakArr.size();
    quint8 dispbytes=34;                //双行显示屏显示长度34,四行屏显示长度72

    sendData.clear();
    sendData.append(0x5c);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码,取值255表示不响

    QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());
    bool status;
    sendData.append(swithno.toUInt(&status,16));       //选择继电器
    quint16 deltime=ui->spinBox_swit->value();
    sendData.append(deltime % 256);                    //延时低位
    sendData.append(deltime / 256);                    //延时高位

    sendData.append(ui->spinBox_dispdelay->value());   //文字显示时长,
    quint8 begindisp =0;                               //在显示屏中的哪个位置开始显示,一般取0
    sendData.append(begindisp);
    sendData.append(dispbytes);                        //显示文字长度
    sendData.append(speakbytes);                       //tts语音长茺

    QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是为了确保满屏34位显示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;i<dispbytes;i++){
        sendData.append(Dispbyte[i]);       //显示信息
    }
    for(int i=0;i<speakbytes;i++){
        sendData.append(SpeakArr[i]);       //TTS语音信息
    }

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);

    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//驱动设备显示文字+蜂鸣响声+播报固定组合语音+开启继电器开关------------------------------------------------------------------------------
void MainWindow::on_PBSendDispSpk_clicked()
{
    QByteArray speakcode; //选择加入要播报的语音代码,最多可加入21个,各语音代码参看 语音列表栏
    speakcode.append(36);speakcode.append(1);speakcode.append(11);speakcode.append(2);speakcode.append(10);
    speakcode.append(3);speakcode.append(17);speakcode.append(4);speakcode.append(16);speakcode.append(5);speakcode.append(15);

    qint8 lensy=speakcode.size();                      //语音代码长度
    quint8 begindisp =0;                               //在显示屏中的哪个位置开始显示,一般取0
    quint8 dispbytes=34;                               //双行显示屏显示长度34

    sendData.clear();
    sendData.append(0x5b);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码,取值255表示不响

    QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex());
    bool status;
    sendData.append(swithno.toUInt(&status,16));       //选择继电器
    quint16 deltime=ui->spinBox_swit->value();
    sendData.append(deltime % 256);                    //延时低位
    sendData.append(deltime / 256);                    //延时高位

    sendData.append(ui->spinBox_dispdelay->value());   //文字显示时长,

    sendData.append(begindisp);                        //显示起始位置
    sendData.append(dispbytes);                        //显示字符串长度
    sendData.append(lensy);                            //语音代码条数

    QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是为了确保满屏34位显示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;i<dispbytes;i++){
        sendData.append(Dispbyte[i]);       //显示信息
    }
    for(int i=0;i<lensy;i++){
        sendData.append(speakcode[i]);      //语音信息
    }

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);

    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//指定扇区密钥读取M1卡扇区数据----------------------------------------------------------------------------------------
void MainWindow::on_PBReadCard_clicked()
{
    unsigned char cardnobuf[4];      //卡号
    unsigned char keybuf[6];         //密钥
    int keylen;
    int cardnolen;

    QString cardnostr ="00000000";   // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号
    cardnolen=checkhexdata(cardnostr,cardnobuf);
    if(cardnolen<4){
        QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!");
        ui->textEdit_M1UID->setFocus();
        return;
    }

    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=checkhexdata(keyinf,keybuf);
    if(keylen<6){
        QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");
        ui->textEdit_authkey->setFocus();
        return;
    }

    sendData.clear();
    sendData.append(0x3b);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(0x01);                             //本次操作的区数
    for (int i=0 ;i<4;i++){                            //指定读写的卡号,全为0 表示可读写任意卡
        sendData.append(cardnobuf[i]);
    }
    sendData.append(ui->CBPage->currentIndex());       //本次操作的扇区号
    sendData.append(ui->CBauth->currentIndex());       //为1以B密码来验证旧密码,为0以A密码来验证旧密码
    for (int i=0 ;i<6;i++){
        sendData.append(keybuf[i]);                    //认证密钥
    }
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}


//指定扇区密钥写入数据到M1卡扇区----------------------------------------------------------------------------------------
void MainWindow::on_PBWriteCard_clicked()
{
    unsigned char cardnobuf[4];      //卡号
    unsigned char keybuf[6];         //密钥
    unsigned char databuf[50];       //写卡数据
    int keylen;
    int cardnolen;
    int datalen;

    QString cardnostr ="00000000";   // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号
    cardnolen=checkhexdata(cardnostr,cardnobuf);
    if(cardnolen<4){
        QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!");
        ui->textEdit_M1UID->setFocus();
        return;
    }

    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=checkhexdata(keyinf,keybuf);
    if(keylen<6){
        QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");
        ui->textEdit_authkey->setFocus();
        return;
    }

    QString datastr = ui->textEdit_data->toPlainText().trimmed();
    datalen=checkhexdata(datastr,databuf);
    if(datalen<48){
        int answ=QMessageBox::question (this, "警告", "有效的写卡数据不足一扇区48字节,是否要补0写入?", QMessageBox::Ok, QMessageBox::Cancel);
        if (answ !=1024){
            ui->textEdit_data->setFocus();
            return;
        }
    }

    sendData.clear();
    sendData.append(0x3d);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(0x01);                             //本次操作的区数
    for (int i=0 ;i<4;i++){                            //指定读写的卡号,全为0 表示可读写任意卡
        sendData.append(cardnobuf[i]);
    }
    sendData.append(ui->CBPage->currentIndex());       //本次操作的扇区号
    sendData.append(ui->CBauth->currentIndex());       //为1以B密码来验证旧密码,为0以A密码来验证旧密码
    for (int i=0 ;i<6;i++){
        sendData.append(keybuf[i]);                    //认证密钥
    }
    for (int i=0 ;i<48;i++){
        sendData.append(databuf[i]);                    //写卡数据
    }

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

//修改M1卡扇区密钥-------------------------------------------------------------------------------------------------
void MainWindow::on_PBChangeKey_clicked()
{
    int answ=QMessageBox::question (this, "警告", "执行此操作前请记住卡片新密钥,否则卡片将报废!是否继续?", QMessageBox::Ok, QMessageBox::Cancel);
    if (answ !=1024){
        ui->textEdit_data->setFocus();
        return;
    }
    unsigned char cardnobuf[4];      //卡号
    unsigned char keybuf[6];         //密钥
    unsigned char newkeybuf[20];     //新密钥
    int keylen;
    int cardnolen;
    int newkeylen;

    QString cardnostr ="00000000";   // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号
    cardnolen=checkhexdata(cardnostr,cardnobuf);
    if(cardnolen<4){
        QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!");
        ui->textEdit_M1UID->setFocus();
        return;
    }

    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=checkhexdata(keyinf,keybuf);
    if(keylen<6){
        QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");
        ui->textEdit_authkey->setFocus();
        return;
    }

    QString newkey = ui->textEdit_newkey->toPlainText().trimmed();
    newkeylen=checkhexdata(newkey,newkeybuf);
    if(newkeylen<16){
        QMessageBox::critical(NULL, "提示", "请输16进制 6字节A密码+4字节控制位+6字节B密码 !");
        ui->textEdit_newkey->setFocus();
        return;
    }

    sendData.clear();
    sendData.append(0x3a);                             //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //机号低位
    sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    sendData.append(0x01);                             //本次操作的区数
    for (int i=0 ;i<4;i++){                            //指定读写的卡号,全为0 表示可读写任意卡
        sendData.append(cardnobuf[i]);
    }
    sendData.append(ui->CBPage->currentIndex());       //本次操作的扇区号
    quint8 auth=ui->CBauth->currentIndex();            //为1以B密码来验证旧密码,为0以A密码来验证旧密码
    auth=auth+ui->ChangeKey->currentIndex()*2;         //修改A、B、控制位
    sendData.append(auth);

    for (int i=0 ;i<6;i++){
        sendData.append(keybuf[i]);                    //认证密钥
    }
    for (int i=0 ;i<16;i++){
        sendData.append(newkeybuf[i]);                 //新A密钥、控制位、B密钥
    }

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}


void MainWindow::on_PBSetRW_clicked()
{
    unsigned char keybuf[6];         //密钥
    int keylen;

    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=checkhexdata(keyinf,keybuf);
    if(keylen<6){
        QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!");
        ui->textEdit_authkey->setFocus();
        return;
    }

    quint8 Sector= ui->CBPage->currentIndex();           //扇区号
    quint8 pages;
    int answ=QMessageBox::information (this, "提示", "按 OK 键把读写器设为主动读取"+QString::asprintf("%d",Sector)+"扇区数据,按 No 键将读写器设为只读卡号不读扇区数据,按 Cancel 退出本次操作。", QMessageBox::Ok | QMessageBox::No | QMessageBox::Cancel);
    if (answ==QMessageBox::No){
        pages=0;
        sendData.clear();
        sendData.append(0x4b);                             //功能码
        quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
        sendData.append(devno % 256);                      //机号低位
        sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
        sendData.append(pages);                            //本次操作的区数
        sendData.append(0x55);      //防干扰后缀
        sendData.append(0xaa);
        sendData.append(0x66);
        sendData.append(0x99);
        SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
    }else if(answ==QMessageBox::Ok){
        pages=1;
        sendData.clear();
        sendData.append(0x4b);                             //功能码
        quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
        sendData.append(devno % 256);                      //机号低位
        sendData.append(devno / 256);                      //机号高位,高低位都为0表示所有机
        sendData.append(pages);                            //主动读取的扇区数,如果要开通几个扇区这里就填几
        if (ui->CBauth->currentIndex()==0){Sector=Sector+128;}
        sendData.append(Sector);                           //扇区号及密码认证类型
        for (int i=0;i<6;i++){
            sendData.append(keybuf[i]);                    //扇区认证密钥
        }                                                  //如果读多个扇区也按此结构加入,可以开通全部的16个扇区
        sendData.append(0x55);      //防干扰后缀
        sendData.append(0xaa);
        sendData.append(0x66);
        sendData.append(0x99);
        SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
    }
}


void MainWindow::on_PBcopylist_clicked()
{
    QString listinf;
    int row=ui->listWidget->count();
    if (row<1){
        return;
    }else{
        for (int i=0;i<row;i++){
            QListWidgetItem *item = ui->listWidget->item(i);
            listinf=listinf+item->text()+"\n";
        }
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(listinf);
        QMessageBox::information(this, "提示", "显示数据报文已拷贝到剪切板");
    }
}

//接收到刷卡数据立即回应--------------------------------------------------------------------------
void MainWindow::Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber)
{
    QByteArray RespBuff;
    RespBuff.append(0x5A);                             //功能码
    quint16 devno=DeviceNumber.toUInt();
    RespBuff.append(devno % 256);                      //机号低位
    RespBuff.append(devno / 256);                      //机号高位,高低位都为0表示所有机
    RespBuff.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码,255表示不响声
    RespBuff.append(ui->spinBox_dispdelay->value());   //文字显示时长,
    QString dispstr=Dispinf+"                                  ";  //加空格是为了确保满屏34位显示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;i<34;i++){
        RespBuff.append(Dispbyte[i]);
    }

    udpSocket->writeDatagram(RespBuff.constData(), RespBuff.size(), QHostAddress(ip), port);

    QString SendHex=getsystime()+" Send To: "+(ip.toString()+":"+QString::asprintf("%d",port)+"             ").mid(0,22);
    SendHex=SendHex+ByteArrayToHexString(RespBuff);
    listadditems(0,SendHex);
}

void MainWindow::on_pushButton_9_clicked()
{
    ui->scrollArea->setVisible(false);
}


void MainWindow::on_pushButton_clicked()
{
    ui->New_ServerIP->setText(ui->CBIP->currentText().trimmed());
}


void MainWindow::on_pushButton_2_clicked()
{
    ui->New_ServerIP->setText("255.255.255.255");
    ui->ServerMAC->setText("FF-FF-FF-FF-FF-FF");
    ui->radioButton1->setChecked(true);
    ui->radioButton2->setChecked(false);
}


void MainWindow::on_pushButton_4_clicked()
{
    ui->New_ServerIP->setText("119.29.167.63");
    ui->ServerMAC->setText("FF-FF-FF-FF-FF-FF");
    ui->radioButton1->setChecked(true);
    ui->radioButton2->setChecked(false);
}



void MainWindow::on_pushButton_3_clicked()
{
    QString serverip=ui->CBIP->currentText().trimmed();
    ui->New_ServerIP->setText(serverip);
    QString servermac=getMacByIp(serverip);
    servermac=servermac.replace(":","-");
    if(servermac==""){servermac="FF-FF-FF-FF-FF-FF";}
    ui->ServerMAC->setText(servermac);
}


void MainWindow::on_pushButton_7_clicked()
{
    QString gateway=ui->New_Gateway->text().trimmed();
    QString gatemac=getMacByIp(gateway);
    gatemac=gatemac.replace(":","-");
    if (gatemac==""){gatemac="FF-FF-FF-FF-FF-FF";}
    ui->GateWayMac->setText(gatemac);
}


void MainWindow::on_pushButton_8_clicked()
{
    if (ui->radioButton1->isChecked()){ui->ServerMAC->setText("FF-FF-FF-FF-FF-FF");}
    if (ui->radioButton3->isChecked()){ui->GateWayMac->setText("FF-FF-FF-FF-FF-FF");}

    QString newip=ui->New_IP->text().trimmed();
    if (!isValidIP(newip)){
        QMessageBox::critical(NULL, "提示", "请输入有效的设备IP!");
        ui->New_IP->setFocus();
        return;
    }
    QString newmask=ui->New_Mask->text().trimmed();
    if (!isValidIP(newmask)){
        QMessageBox::critical(NULL, "提示", "请输入有效的设备掩码!");
        ui->New_Mask->setFocus();
        return;
    }
    QString newserverip=ui->New_ServerIP->text().trimmed();
    if (!isValidIP(newserverip)){
        QMessageBox::critical(NULL, "提示", "请输入有效的远程服务器ip!");
        ui->New_ServerIP->setFocus();
        return;
    }
    QString newgateway=ui->New_Gateway->text().trimmed();
    if (!isValidIP(newgateway)){
        QMessageBox::critical(NULL, "提示", "请输入有效的网关!");
        ui->New_Gateway->setFocus();
        return;
    }
    QString servermac=ui->ServerMAC->text().trimmed();
    if (!isValidMac(servermac)){
        QMessageBox::critical(NULL, "提示", "请输入有效的远程服务器MAC!");
        ui->ServerMAC->setFocus();
        return;
    }
    QString gatemac=ui->GateWayMac->text().trimmed();
    if (!isValidMac(gatemac)){
        QMessageBox::critical(NULL, "提示", "请输入有效的网关MAC!");
        ui->GateWayMac->setFocus();
        return;
    }
    bool ok;
    sendData.clear();
    sendData.append(0xf9);                   //功能码
    QStringList liststr = newip.split(".");  //新IP
    for (int i=0 ;i<4;i++){
        sendData.append(liststr[i].toInt());
    }
    liststr = newmask.split(".");            //掩码
    for (int i=0 ;i<4;i++){
        sendData.append(liststr[i].toInt());
    }
    liststr = newserverip.split(".");        //远程服务器IP
    for (int i=0 ;i<4;i++){
        sendData.append(liststr[i].toInt());
    }
    liststr = servermac.split("-");         //远程服务器MAC
    for (int i=0 ;i<6;i++){
        sendData.append(liststr[i].toInt(&ok,16));
    }
    liststr = newgateway.split(".");        //网关
    for (int i=0 ;i<4;i++){
        sendData.append(liststr[i].toInt());
    }
    liststr = gatemac.split("-");           //网关MAC
    for (int i=0 ;i<6;i++){
        sendData.append(liststr[i].toInt(&ok,16));
    }
    quint16 devno=ui->New_Nember->text().toUInt();
    sendData.append(devno % 256);           //机号低位
    sendData.append(devno / 256);           //机号高位,高低位都为0表示所有机

    quint16 newport=ui->New_Port->text().toInt();
    sendData.append(newport % 256);         //端口低位
    sendData.append(newport / 256);         //端口高位

    QString seri=ui->Serial_Number->text().trimmed();
    liststr = seri.split("-");              //模块序号
    for (int i=0 ;i<4;i++){
        sendData.append(liststr[i].toInt());
    }

    quint8 searchid=0;
    if (ui->checkBox_beep->isChecked()){searchid=searchid+1;}
    if (ui->radioButton1->isChecked()){searchid=searchid+2;}
    if (ui->radioButton3->isChecked()){searchid=searchid+4;}
    if (ui->checkBox_dhcp->isChecked()){searchid=searchid+8;}
    if (ui->comboBox_out->currentIndex()==1){searchid=searchid+16;}
    searchid=searchid+ ui->comboBox_in->currentIndex()*32;
    sendData.append(searchid);

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);

    if (ui->checkBox_broadcast->isChecked()){   //使用广播方式发送指令
        QHostAddress broadcastAddress("255.255.255.255");
        quint16 port1 = 39169;
        udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);
        QString  dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22) ;
        dispinf=dispinf+ByteArrayToHexString(sendData);
        listadditems(0,dispinf);
    }else{
        SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
    }
}


void MainWindow::on_pushButton_SetTCP_clicked()
{
    sendData.clear();
    sendData.append(0x1d);                  //功能码
    quint16 devno=0;                        //机号,0表示所有机
    sendData.append(devno % 256);           //机号低位
    sendData.append(devno / 256);           //机号高位,高低位都为0表示所有机
    sendData.append(7);                     //指令长度
    sendData.append(0x5c);                  //修改TCP通讯端口功能码
    sendData.append(4);                     //数据长度

    quint16 devport=ui->New_Port->text().toUInt(); //读卡器端口
    sendData.append(devport % 256);           //低位
    sendData.append(devport / 256);           //高位

    quint16 serverport=ui->lineEdit_TCPRemoPort->text().toUInt(); //远程TCP服务器端口
    sendData.append(serverport % 256);        //低位
    sendData.append(serverport / 256);        //高位

    quint8 crc=sendData[6]^sendData[7]^sendData[8]^sendData[9];    //数据校验位
    sendData.append(crc);

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);

    if (ui->checkBox_broadcast->isChecked()){   //使用广播方式发送指令
        QHostAddress broadcastAddress("255.255.255.255");
        quint16 port1 = 39169;
        udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);
        QString  dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22) ;
        dispinf=dispinf+ByteArrayToHexString(sendData);
        listadditems(0,dispinf);
    }else{
        SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
    }
}


void MainWindow::on_pushButton_SetHttp_clicked()
{
    QString filenamestr=ui->lineEdit_filename->text().trimmed();
    QByteArray filebyte=filenamestr.toLocal8Bit();
    if(filebyte.size()<1){
        QMessageBox::critical(NULL, "提示", "请输入正确的访问文件,可以是.asp\\.jsp\\.php等脚本文件!");
        ui->lineEdit_filename->setFocus();
        return;
    }
    sendData.clear();
    sendData.append(0x1d);                  //功能码
    quint16 devno=0;                        //机号,0表示所有机
    sendData.append(devno % 256);           //机号低位
    sendData.append(devno / 256);           //机号高位,高低位都为0表示所有机
    sendData.append(filebyte.size()+7);     //指令长度
    sendData.append(0x5b);                  //设置http协议读卡器访问文件、端口、提效方式的识别码
    sendData.append(filebyte.size()+4);     //数据长度
    sendData.append(ui->comboBox_Sendmodel->currentIndex()); //提交方式
    sendData.append(0xff);

    quint16 serverport=ui->lineEdit_HttpRemoPort->text().toUInt(); //远程http服务器端口
    sendData.append(serverport % 256);        //低位
    sendData.append(serverport / 256);        //高位

    quint8 crc= sendData[6]^ sendData[7]^ sendData[8]^sendData[9];

    for(int i=0;i<filebyte.size();i++){
        sendData.append(filebyte[i]);       //访问文件
        crc=crc ^filebyte[i];
    }
    sendData.append(crc);

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);

    if (ui->checkBox_broadcast->isChecked()){   //使用广播方式发送指令
        QHostAddress broadcastAddress("255.255.255.255");
        quint16 port1 = 39169;
        udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);
        QString  dispinf=getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22) ;
        dispinf=dispinf+ByteArrayToHexString(sendData);
        listadditems(0,dispinf);
    }else{
        SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
    }
}


void MainWindow::on_pushButton_16_clicked()
{
    ui->scrollArea_wifi->setVisible(false);
}


void MainWindow::on_PBClear_2_clicked()
{
    ui->scrollArea->setVisible(false);
    ui->scrollArea_wifi->setVisible(true);
}


void MainWindow::on_radioButton_IP_toggled(bool checked)
{
    if(ui->radioButton_IP->isChecked()){
        ui->groupBox_dhcp->setVisible(true);
    }else{
        ui->groupBox_dhcp->setVisible(false);
    }
}


void MainWindow::on_pushButton_SetUp_clicked()
{
    QString wifiName=ui->lineEdit_SSID->text().trimmed();
    QByteArray wifiNamearry=wifiName.toUtf8();      //注意编码格式
    if(wifiNamearry.size()<1 || wifiNamearry.size()>60){
        QMessageBox::critical(NULL, "提示", "WIFI热点名称长度不可大于60,不可为空!");
        ui->lineEdit_SSID->setFocus();
        return;
    }

    QString wifipass=ui->lineEdit_Password->text().trimmed();
    QByteArray wifipassarry=wifipass.toUtf8();      //注意编码格式
    if(wifipassarry.size()>64){
        QMessageBox::critical(NULL, "提示", "WIFI密码长度不可以大于64!");
        ui->lineEdit_Password->setFocus();
        return;
    }

    sendData.clear();
    sendData.append(0xf7);                  //功能码
    quint16 devno=0;                        //机号,0表示所有机
    sendData.append(devno % 256);           //机号低位
    sendData.append(devno / 256);           //机号高位,高低位都为0表示所有机
    sendData.append(wifiNamearry.size());   //热点名称长度
    quint8 passlen=0;
    if(ui->checkBox_wifikey->isChecked()){
        passlen=wifipassarry.size();
    }
    sendData.append(passlen);                //密码长度

    int i=0;
    for (i=0;i<wifiNamearry.size();i++){
        sendData.append(wifiNamearry[i]);
    }
    quint8 bytebit=0;
    while (sendData.size()<65){
        sendData.append(bytebit);
    }

    for (i=0;i<passlen;i++){
        sendData.append(wifipassarry[i]);
    }
    while (sendData.size()<129){
        sendData.append(bytebit);
    }

    if(ui->radioButton_IP->isChecked()){
        sendData.append(1);
        QString ipstr=ui->lineEdit_IP->text().trimmed();
        if (!isValidIP(ipstr)){
            QMessageBox::critical(NULL, "提示", "请输入有效的设备IP!");
            ui->lineEdit_IP->setFocus();
            return;
        }
        QString mskstr=ui->lineEdit_mask->text().trimmed();
        if (!isValidIP(mskstr)){
            QMessageBox::critical(NULL, "提示", "请输入正确的读卡器子网掩码!");
            ui->lineEdit_mask->setFocus();
            return;
        }
        QString gatewaystr=ui->lineEdit_gateway->text().trimmed();
        if (!isValidIP(gatewaystr)){
            QMessageBox::critical(NULL, "提示", "请输入正确的读卡器网关!");
            ui->lineEdit_mask->setFocus();
            return;
        }
        QStringList liststr = ipstr.split(".");  //IP
        for (int i=0 ;i<4;i++){
            sendData.append(liststr[i].toInt());
        }
        liststr = mskstr.split(".");             //掩码
        for (int i=0 ;i<4;i++){
            sendData.append(liststr[i].toInt());
        }
        liststr = gatewaystr.split(".");         //网关
        for (int i=0 ;i<4;i++){
            sendData.append(liststr[i].toInt());
        }

    }else{
        sendData.append(bytebit);
        while (sendData.size()<142){
            sendData.append(bytebit);
        }
    }

    sendData.append(ui->comboBox_Sendmode->currentIndex());

    sendData.append(0x55);      //防干扰后缀
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}


void MainWindow::on_pushButton_Read_clicked()
{
    ui->listWidget_wifi->clear();
    sendData.clear();
    sendData.append(0xa4);                  //功能码
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);           //机号低位
    sendData.append(devno / 256);           //机号高位,高低位都为0表示所有机
    SendBuffAct();        //将sendData缓冲数据发送到指定的设备IP端口
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1797720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习】训练GNN图神经网络模型进行节点分类

1. 引言 1.1 图神经网络GNN概述 图神经网络&#xff08;Graph Neural Network&#xff0c;GNN&#xff09;是一种专门用于处理图结构数据的神经网络方法。它起源于2005年&#xff0c;当时Gori等人首次提出了GNN的概念&#xff0c;用于学习图中的节点特征以及它们之间的关系。…

Doris 少数SQL在Datagrip无法执行,而在DorisUI或程序调用可以执行的问题

问题&#xff1a;Doris 少数SQL在Datagrip无法执行&#xff0c;而在DorisUI或程序调用可以执行 解决&#xff1a;Datagrip 执行SQL切分异常&#xff0c;设置默认执行语句方式&#xff0c;将分句改为整句执行 但是 支持多SQL批量分开执行更好用

英伟达的数字孪生地球是什么

1 英伟达的数字孪生地球 Earth-2是一个全栈式开放平台&#xff0c;包含&#xff1a;ICON 和 IFS 等数值模型的物理模拟&#xff1b;多种机器学习模型&#xff0c;例如 FourCastNet、GraphCast 和通过 NVIDIA Modulus 实现的深度学习天气预测 (DLWP)&#xff1b;以及通过 NVIDI…

大学电工基础与电子设计试题及答案,分享几个实用搜题和学习工具 #其他#经验分享

学习和考试是大学生生活中不可避免的一部分&#xff0c;而在这个信息爆炸的时代&#xff0c;如何快速有效地获取学习资源和解答问题成为了大学生们共同面临的难题。为了解决这个问题&#xff0c;搜题和学习软件应运而生。今天&#xff0c;我将为大家介绍几款备受大学生青睐的搜…

Vue进阶之Vue无代码可视化项目(一)

Vue无代码可视化项目 项目搭建初始步骤拓展:工程项目从0-1项目规范化package.jsoncpell.jsoncustom-words.txtts-eslint规则.eslintrc.cjsgit钩子检查有没有问题type-checkspellchecklint:stylehusky操作安装pre-commitpnpm的commit规范package.json:commitlint.config.cjs安装…

深度解析Linux内核中fork工作原理和实现

Linux内核中的fork()系统调用是用来创建新进程的核心机制。它的主要工作是为新创建的子进程复制当前进程(父进程)的数据结构和内存空间,从而产生一个几乎完全相同的副本。fork()的实现涉及到操作系统内核中许多重要部分的交互和协作,过程比较复杂。 fork()的基本原理 当一个进…

ThinkPHP发邮件配置教程?群发功能安全吗?

ThinkPHP发邮件的注意事项&#xff1f;如何优化邮件发送的性能&#xff1f; 无论是用户注册、密码重置还是消息提醒&#xff0c;发送邮件都是一个常见的需求。AokSend将详细介绍如何在ThinkPHP框架中配置和发送邮件&#xff0c;帮助开发者轻松实现邮件功能。 ThinkPHP发邮件&…

【全开源】同城招聘SAAS信息前程无忧直聘达小程序

招聘SAAS&#xff1a;数字化转型中的招聘新助力 基于ThinkPHP和原生微信小程序开发的招聘平台系统&#xff0c;包含微信小程序求职者端、微信小程序企业招聘端、PC企业招聘端、PC管理平台端​ &#x1f31f; 一、招聘SAAS简介 在人力资源领域&#xff0c;数字化转型已成为不…

铁塔、烟囱建筑倾斜监测的倾角仪的分类以及工作原理

前言 倾角传感器是一种用于测量物体相对平面倾斜角度的仪器。倾角传感器又称作倾角仪、倾斜仪、测斜仪、水平仪、倾角计&#xff0c;经常用于物体的水平角度变化的精确测量&#xff0c;用它可测量被测平面相对于水平位置的倾斜度、两部件相互平行度和垂直度&#xff1b;已成为桥…

南京代理记账公司,为您提供专业服务,助力企业发展

在当今社会&#xff0c;企业的经营情况需要通过各种方式来进行监督和管理&#xff0c;记账是企业日常运营中不可或缺的一部分&#xff0c;对于非专业的财务人员来说&#xff0c;如何进行正确、有效的记账呢&#xff1f;这就需要找一家专业的代理记账公司来帮助您。 南京代理记账…

工程力学 - 课程导论

工程力学是工程学科中的核心基础课程&#xff0c;专注于研究物体在外力作用下的运动规律和受力情况。它涵盖了静力学、运动学、动力学和材料力学等关键领域&#xff0c;为工程结构的安全性、稳定性和功能性提供理论支撑。通过理论分析、实验测定和计算机模拟等方法&#xff0c;…

Hikyuu教程:简单波动率(EMV)择时交易系统的构建与实现

今日&#xff0c;我们将探讨如何借助 hikyuu 框架实现简单波动指标 EMV 的择时系统。与以往稍有不同的是&#xff0c;本次我们将采用策略部件仓库的写法来完成示例代码&#xff0c;以便大家进一步了解和熟悉仓库的使用方法。 什么是简易波动指标&#xff08;EMV&#xff09; …

[ubuntu]docker 卡登录 You‘ve been signed out

Setting->Resources->Proxies设置当前使用的proxies即可 参考&#xff1a;https://github.com/docker/for-mac/issues/7160#issuecomment-2061040813

香蕉派BPI-F3 进迭时空(SpacemiT)K1RISC-V开发板软件下载链接

香蕉派BPI-F3是一款工业级 8核RISC-V开源硬件开发板&#xff0c;它采用进迭时空&#xff08;SpacemiT&#xff09; K1 8核RISC-V芯片设计&#xff0c;CPU集成2.0 TOPs AI计算能力。4G DDR和16G eMMC。2个GbE以太网接口&#xff0c;4个USB 3.0和PCIe M.2接口&#xff0c;支持HDM…

Sylar C++高性能服务器学习记录21 【ByteArray模块-知识储备篇】

早在19年5月就在某站上看到sylar的视频了&#xff0c;一直认为这是一个非常不错的视频。 由于本人一直是自学编程&#xff0c;基础不扎实&#xff0c;也没有任何人的督促&#xff0c;没能坚持下去。 每每想起倍感惋惜&#xff0c;遂提笔再续前缘。 为了能更好的看懂sylar&…

HTML静态网页成品作业(HTML+CSS)—— 金宝贝儿童教育机构介绍网页(2个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有2个页面。 二、作品演示 三、代…

社交创新:Facebook的技术与产品发展

在当今数字化时代&#xff0c;社交网络已经渗透到我们生活的方方面面&#xff0c;成为了人们日常交流、信息获取和社交互动的主要方式。而在这个众多社交平台中&#xff0c;Facebook作为其中的佼佼者&#xff0c;其技术与产品的发展历程也是一个社交创新的缩影。本文将探索Face…

从写简历到谈薪资的最全教程

从写简历到谈薪资的最全教程 目录简历注意事项举个例子写简历投递简历也有技巧模拟面试的重要性面试经验怎么刷不断迭代达越来越强斗智斗勇谈薪资拿到offer就结束了吗&#xff1f;我能给你的帮助 目录 大家好&#xff0c;我是一名普通本科毕业的学生&#xff0c;工作数年&#…

git根据历史某次提交创建新分支

有时候项目在做版本管理的时候&#xff0c;忘记了创建某次版本的分支&#xff0c;而直接在主分支上进行开发了&#xff0c;这个时候&#xff0c;想要对某次提交单独拉出来一个版本分支&#xff0c;就需要用到这个功能&#xff1a; git checkout -b 新分支名 某次提交的id 找到…

最新 Navicat Data Modeler 4 | 产品介绍

在过去的几周里&#xff0c;我们已经介绍了 Navicat 版本 17&#xff0c;现在我们来把注意力转移到另外两个值得关注的产品上&#xff0c;即 Navicat Data Modeler 和 Navicat BI&#xff08;之前称为 Navicat Chart Creator&#xff09;。今天的博客将介绍 Navicat Data Model…