0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ID讀卡器TCP協(xié)議QT小程序開發(fā)

鄒振豪 ? 作者:jf_51178285 ? 2024-12-31 10:19 ? 次閱讀

ID卡網(wǎng)絡(luò)讀卡器TCP協(xié)議QT小程序開發(fā)。

TCP(傳輸控制協(xié)議,Transmission Control Protocol)是互聯(lián)網(wǎng)中最核心、最基本的協(xié)議之一。以下是對TCP協(xié)議的詳細(xì)介紹:

一、基本概念
TCP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。它工作在OSI模型的第四層,即傳輸層,為用戶提供可靠的、有序的和無差錯(cuò)的數(shù)據(jù)傳輸服務(wù)。TCP協(xié)議與UDP協(xié)議是傳輸層的兩大主要協(xié)議,但兩者在設(shè)計(jì)上有明顯的不同:TCP提供的是可靠的數(shù)據(jù)傳輸服務(wù),而UDP則更注重傳輸?shù)乃俣群托省?/p>

二、技術(shù)特點(diǎn)
1.面向連接:TCP在傳輸數(shù)據(jù)之前,必須先建立連接,確保數(shù)據(jù)的傳輸路徑是可靠的。連接建立后,TCP會維護(hù)一個(gè)連接狀態(tài),包括序列號、窗口大小等信息,用于保證數(shù)據(jù)傳輸?shù)挠行蛐院涂煽啃浴?br /> 2.可靠傳輸:TCP通過確認(rèn)重傳機(jī)制、滑動窗口機(jī)制、超時(shí)重傳機(jī)制等方式,確保數(shù)據(jù)在傳輸過程中不會丟失、不會重復(fù)、不會亂序。具體來說,TCP會給每個(gè)報(bào)文段分配一個(gè)序列號,接收方根據(jù)序列號確認(rèn)數(shù)據(jù)的順序和完整性。如果接收方發(fā)現(xiàn)數(shù)據(jù)丟失或亂序,會要求發(fā)送方重傳。
3.字節(jié)流傳輸:TCP將應(yīng)用層發(fā)送的數(shù)據(jù)劃分成以字節(jié)為單位的報(bào)文段,并進(jìn)行序列號標(biāo)記。這種方式能夠確保數(shù)據(jù)在傳輸過程中不會被拆分或丟失,從而保證數(shù)據(jù)的完整性。
4.全雙工通信:TCP允許雙方在任何時(shí)候都能發(fā)送數(shù)據(jù),為此TCP連接的兩端都設(shè)有發(fā)送緩存和接收緩存,用來臨時(shí)存放雙向通信的數(shù)據(jù)。
三、工作原理
1.連接建立:TCP連接建立采用三次握手過程。首先,客戶端向服務(wù)器發(fā)送一個(gè)SYN報(bào)文段,請求建立連接。服務(wù)器收到后,回復(fù)一個(gè)SYN-ACK報(bào)文段,表示同意建立連接并確認(rèn)客戶端的SYN報(bào)文段。最后,客戶端再發(fā)送一個(gè)ACK報(bào)文段,確認(rèn)服務(wù)器的SYN-ACK報(bào)文段。至此,TCP連接建立完成。
2.數(shù)據(jù)傳輸:在連接建立后,雙方可以開始傳輸數(shù)據(jù)。TCP會將應(yīng)用層發(fā)送的數(shù)據(jù)劃分成報(bào)文段,并添加TCP頭部信息(包括序列號、窗口大小等),然后交給IP層進(jìn)行傳輸。接收方收到報(bào)文段后,會進(jìn)行校驗(yàn)和檢查、序列號確認(rèn)等操作,確保數(shù)據(jù)的完整性和順序性。如果發(fā)現(xiàn)問題,會要求發(fā)送方重傳。
3.連接終止:TCP連接終止采用四次揮手過程。首先,一方發(fā)送一個(gè)FIN報(bào)文段,表示要關(guān)閉連接。另一方收到后,回復(fù)一個(gè)ACK報(bào)文段,表示同意關(guān)閉連接但還有數(shù)據(jù)要發(fā)送。當(dāng)所有數(shù)據(jù)發(fā)送完畢后,另一方再發(fā)送一個(gè)FIN報(bào)文段,表示關(guān)閉連接。最后,接收方回復(fù)一個(gè)ACK報(bào)文段,確認(rèn)連接關(guān)閉。至此,TCP連接終止完成。
四、應(yīng)用場景
TCP協(xié)議廣泛應(yīng)用于需要可靠傳輸?shù)膱龊?,如HTTP、FTP等協(xié)議都基于TCP協(xié)議進(jìn)行數(shù)據(jù)傳輸。此外,TCP還用于數(shù)據(jù)庫連接、遠(yuǎn)程登錄等需要穩(wěn)定連接的場合。

綜上所述,TCP協(xié)議是一種高效、穩(wěn)定且可靠的傳輸層協(xié)議,它通過多種機(jī)制確保數(shù)據(jù)的可靠傳輸和有序性。在互聯(lián)網(wǎng)傳輸中,TCP協(xié)議發(fā)揮著重要作用。

wKgZPGdzTm2AN68GAAPBNk4wtZw082.png

QT開發(fā)示例的UI界面如下:

wKgZO2dzTo-AcDnNAAJEiGfZ3j0291.png

mainWindow.cpp代碼如下:

bool listening=false;               //sock偵聽標(biāo)志
QByteArray sendData;                //發(fā)送數(shù)據(jù)緩沖
 
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{    
    ui->setupUi(this);
 
    ui->scrollArea->setVisible(false);    
    ui->scrollArea->move(180,40);
 
    ui->scrollArea_wifi->setVisible(false);
    ui->scrollArea_wifi->move(250,130);
 
    ui->scrollArea_config->setVisible(false);
    ui->scrollArea_config->move(250,130);
 
    ui->groupBox_dhcp->setVisible(false);
 
    QStringList ips = MyClass::getAllIPAddresses();
    foreach (QString ip, ips) {
        ui->CBIP->addItem(ip);
    }
    if(ui->CBIP->count()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);
    }
}
 
//廣播發(fā)送搜索所有在線的設(shè)備-------------------------------------------------------------------------------------------
void MainWindow::on_PBSearch_clicked()
{
    int n = ui->tableWidget->rowCount();//總行數(shù)
    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);        //搜索所有在線設(shè)備
    QString  dispinf=MyClass::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);      //查詢在線設(shè)備型號、固件日期
    dispinf=MyClass::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);  這個(gè)方式是綁定所有網(wǎng)卡,這樣發(fā)不出廣播包
            connect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data);
            listening=true;
            listadditems(0,MyClass::getsystime()+" Sock已啟動偵聽"+ipstr+":"+ui->TEPort->toPlainText());
        }
    }
    catch(_exception)
    {
        listening=false;
        udpSocket->close();
        listadditems(0,MyClass::getsystime()+" Sock偵聽已關(guān)閉!");
    }
}
 
//Socket UDP端口接收數(shù)據(jù)---------------------------------------------------------------------------------------------------------
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=MyClass::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卡扇區(qū)數(shù)據(jù)的返回
        break;
 
    case 0x3c:
        Analyze_3c(ip, port,databuff,buflen);          //主動寫M1卡扇區(qū)數(shù)據(jù)的返回
        break;
 
    case 0xc5:
        Analyze_c5(ip, port,databuff,buflen);          //指定區(qū)號密鑰讀取M1扇區(qū)數(shù)據(jù)返回
        break;
 
    case 0xcd:
        Analyze_cd(ip, port,databuff,buflen);          //指定區(qū)號密鑰寫數(shù)據(jù)到M1卡扇區(qū)返回
        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);          //在線設(shè)備響應(yīng)搜索指令的返回、讀卡器上電開機(jī)上傳設(shè)備信息
        break;
 
    case 0xf6:
        Analyze_f6(ip, port,databuff,buflen);          //在線設(shè)備響應(yīng)查詢型號、固件日期指令的返回
        break;
 
    case 0xa4:
        Analyze_a4(ip, port,databuff,buflen);          //查詢WIFI叁數(shù)的返回
        break;
 
    case 0x4b:
        Analyze_4b(ip, port,databuff,buflen);          //設(shè)置主動讀M1卡扇區(qū)號及認(rèn)證密鑰的返回
        break;
 
    default:
        break;
    }
}
 
//設(shè)置主動讀M1卡扇區(qū)號及認(rèn)證密鑰的返回---------------------------------------------------------------------------------------------------
void MainWindow::Analyze_4b(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]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    ui-?>label_msg_2->setText("設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",設(shè)置讀卡扇區(qū)及認(rèn)證密鑰成功!");
    ui->textEdit_msg->setText("設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",設(shè)置讀卡扇區(qū)及認(rèn)證密鑰成功!");
    if(ui->checkBox_Resp->isChecked()){Respondinfo("設(shè)置讀卡扇區(qū)及認(rèn)證密鑰成功!",ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
}
 
//確認(rèn)接收到的信息----------------------------------------------------------------------------------------------------------------
void MainWindow::DisableSendAgain(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    QString SendHex=MyClass::getsystime()+" Send To: "+(ip.toString()+":"+QString::number(port)+"             ").mid(0,22)+"69 " ;
    sendData.clear();
    sendData.append(0x69);
    for (int i=1;iwriteDatagram(sendData.constData(), sendData.size(), QHostAddress(ip), port);    
    listadditems(0,SendHex+"      確定接收,不要再次發(fā)送此幀數(shù)據(jù)啦...");
}
 
//解析讀取IC卡卡號-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    DisableSendAgain(ip, port,databuff,buflen);//確認(rèn)接收到的信息,否則同一信息讀卡器會重發(fā)三次
 
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //數(shù)據(jù)包號
    QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X", databuff[10],databuff[11],databuff[12],databuff[13]);  //16進(jìn)制卡號正碼
    QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[13],databuff[12],databuff[11],databuff[10]);  //16進(jìn)制卡號反碼
    bool status;
    QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //轉(zhuǎn)8H10D反碼卡號
    QString SerialNumber="";        //設(shè)備全球唯一硬件序號
    for (int i=14;itextEdit_M1UID->setText(CardnoHexZ);
 
    if(ui->checkBox_Resp->isChecked()){Respondinfo(MyClass::getsysdatetime()+"卡號:"+Cardno8H10D,ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
}
 
//主動讀取扇區(qū)數(shù)據(jù)的返回--------------------------------------------------------------------------------------------------------------
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]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    QString CardnoHex="";
    for (int i=12;i=databuff[9]){
        m=databuff[9]*48;
        QString DataHex="";
        for (int i=0;itextEdit_data->setPlainText(DataHex);
        QString DispInf="讀取M1卡扇區(qū)數(shù)據(jù)成功,設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",16進(jìn)制卡號:"+CardnoHex;
        listadditems(1,DispInf);
        ui->textEdit_M1UID->setText(CardnoHex);
 
        if(ui->checkBox_Resp->isChecked()){Respondinfo(MyClass::getsysdatetime()+"卡號:"+CardnoHex,ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
    }
}
 
//主動寫M1卡扇區(qū)數(shù)據(jù)指令的返回--------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_3c(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]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
 
    if(databuff[7]+databuff[8]>=writcardlen){      //全部寫卡數(shù)據(jù)已經(jīng)發(fā)送完畢
        ui->textEdit_msg->setPlainText("設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",寫卡成功!");
        if(ui->checkBox_Resp->isChecked()){Respondinfo("寫扇區(qū)數(shù)據(jù)成功!",ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
    }else{
        QByteArray RespBuff;             //寫卡數(shù)據(jù)超過4個(gè)扇區(qū),需要繼續(xù)發(fā)送
        RespBuff.append(0x3c);           //功能碼
        quint16 devno=0;
        RespBuff.append(devno % 256);    //機(jī)號低位
        RespBuff.append(devno / 256);    //機(jī)號高位,高低位都為0表示所有機(jī)
        RespBuff.append(writcarepoi);    //當(dāng)前已寫扇區(qū)指針
 
        int j=writcardlen - writcarepoi;
        if(j>4){j=4;};
        RespBuff.append(j);              //本次總計(jì)寫扇區(qū)數(shù),一次最多寫4扇區(qū),多于4扇區(qū)要分次寫入
 
        for (int i=0;iwriteDatagram(RespBuff.constData(), RespBuff.size(), QHostAddress(ip), port);
 
        QString SendHex=MyClass::getsystime()+" Send To: "+(ip.toString()+":"+QString::asprintf("%d",port)+"             ").mid(0,22);
        SendHex=SendHex+MyClass::ByteArrayToHexString(RespBuff);
        listadditems(0,SendHex);
 
        writcarepoi=writcarepoi+j;
    }
}
 
//指定區(qū)號密鑰讀取M1扇區(qū)數(shù)據(jù)返回-----------------------------------------------------------------------------------------------------------
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]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    QString CardnoHex="";    
    QString  DispInf="";
    for (int i=8;itextEdit_data->setPlainText(DataHex);
            break;
        }
    case 8:
            DispInf=DispInf+"失敗,設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",沒有卡片在感應(yīng)區(qū)!";
            break;
    case 12:
            DispInf=DispInf+"失敗,設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",16進(jìn)制卡號:"+CardnoHex+",卡密碼認(rèn)證失??!";
            break;
    default:
            DispInf=DispInf+"失敗,設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",錯(cuò)誤代碼:"+QString::asprintf("%d", databuff[13]);
            break;
    }
    listadditems(1,DispInf);
    ui->textEdit_M1UID->setText(CardnoHex);
 
    if(ui->checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
}
 
//指定區(qū)號密鑰寫數(shù)據(jù)到M1卡扇區(qū)返回狀態(tài)---------------------------------------------------------------------------------------------------------
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]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[6]+databuff[7]*256);   //設(shè)備自編機(jī)號
    QString CardnoHex="";
    for (int i=9;icheckBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
}
 
//解析讀取ID卡卡號-----------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_d1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    DisableSendAgain(ip, port,databuff,buflen);//確認(rèn)接收到的信息,否則同一信息讀卡器會重發(fā)三次
 
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //數(shù)據(jù)包號
    QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X%02X", databuff[9],databuff[10],databuff[11],databuff[12],databuff[13]);  //16進(jìn)制卡號正碼,databuff[13]為廠商代碼
    QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[12],databuff[11],databuff[10],databuff[9]);   //16進(jìn)制卡號反碼,databuff[13]為廠商代碼
    bool status;
    QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //轉(zhuǎn)8H10D反碼卡號
    QString SerialNumber="";        //設(shè)備全球唯一硬件序號
    for (int i=14;icheckBox_Resp->isChecked()){Respondinfo(MyClass::getsysdatetime()+"卡號:"+Cardno8H10D,ip,port,DeviceNumber);}  //回應(yīng)驅(qū)動設(shè)備顯示+蜂鳴響聲
}
 
//解析ICID卡離開讀卡器-----------------------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_cf_df(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen)
{
    DisableSendAgain(ip, port,databuff,buflen);//確認(rèn)接收到的信息,否則同一信息讀卡器會重發(fā)三次
 
    QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //數(shù)據(jù)包號
    int infotype=databuff[9];           //數(shù)據(jù)說明,1表示只讀取UID卡號
    int cardnolen=databuff[10];         //UID卡號長度
    QString CardnoHexZ="";              //16進(jìn)制卡號正碼
    for (int i=0;iinsertRow(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); //自動列寬
    }
}
 
//響應(yīng)查詢設(shè)備型號固件日期指令的返回---------------------------------------------------------------------------------------------------
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]);  //設(shè)備IP
    QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256);   //設(shè)備自編機(jī)號
    int NameLen=databuff[7];    //設(shè)備型號名稱長度
    QByteArray namebuf;         //設(shè)備型號
    for (int i=0;itableWidget->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連接狀態(tài)---------------------------------------------------------------------------------------------------------------------
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]); //設(shè)備IP地址,廣域網(wǎng)上使用,一般不對此IP回應(yīng),而是對數(shù)據(jù)流的 ip及端口 回應(yīng)
    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]);       //設(shè)備掩碼
    ui->listWidget_wifi->addItem("WIFI子網(wǎng)掩碼:"+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]); //設(shè)備網(wǎng)關(guān)
    ui->listWidget_wifi->addItem("WIFI網(wǎng)關(guān)地址:"+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]); //網(wǎng)關(guān)MAC
    ui->listWidget_wifi->addItem("網(wǎng)關(guān) MAC地址:"+GatewayMAC);
    switch (databuff[31]){
    case 0:
        ui->listWidget_wifi->addItem("WIFI網(wǎng)絡(luò)狀態(tài):已連接wifi");
        break;
    case 1:
        ui->listWidget_wifi->addItem("WIFI網(wǎng)絡(luò)狀態(tài):連接失??!");
        break;
    case 2:
        ui->listWidget_wifi->addItem("WIFI網(wǎng)絡(luò)狀態(tài):已初始化!");
        break;
    default:
        ui->listWidget_wifi->addItem("WIFI網(wǎng)絡(luò)狀態(tài):未初始化!");
        break;
    }
    QByteArray devname;
    for(int i=0 ;ilistWidget_wifi->addItem("讀卡器  名稱:"+devnamestr);
 
    QByteArray wifname;
     for(int i=0 ;ilistWidget_wifi->addItem("WIFI熱點(diǎn)名稱:"+wifinamestr);
}
 
//更換不同的網(wǎng)卡----------------------------------------------------------------------------------------------------
void MainWindow::on_CBIP_currentIndexChanged(int index)
{
    if (listening){
        disconnect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data);
        udpSocket->close();
        listening=false;
        listadditems(0,MyClass::getsystime()+" Sock偵聽已關(guān)閉!");
    }
    sockinit();
}
 
 
void MainWindow::on_PBClear_clicked()
{
    ui->listWidget->clear();
    ui->textEdit_msg->setText("");
}
 
//在在線設(shè)備列表中選取一臺設(shè)備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 (currentRowscrollArea_wifi->setVisible(false);
        ui->scrollArea->setVisible(true);
        ui->scrollArea_config->setVisible(false);
    }
}
 
//將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備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=MyClass::getsystime()+" Send To: "+(Remoip.toString()+":"+QString::asprintf("%d",Remoport)+"             ").mid(0,22);
    SendHex=SendHex+MyClass::ByteArrayToHexString(sendData);
    listadditems(0,SendHex);
}
 
//驅(qū)動設(shè)備蜂鳴響聲+文字顯示-------------------------------------------------------------------------------------------------
void MainWindow::on_PBSendDispBeep_clicked()
{
    sendData.clear();
    sendData.append(0x5A);                             //功能碼
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(ui->CBbeep->currentIndex());       //蜂鳴響聲代碼,255表示不響聲
    sendData.append(ui->spinBox_dispdelay->value());   //文字顯示時(shí)長,
    QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是為了確保滿屏34位顯示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;itextEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(ui->CBbeep->currentIndex());       //蜂鳴響聲代碼
    SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
}
 
//驅(qū)動設(shè)備開啟繼電器----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBSwitchOn_clicked()
{
    sendData.clear();
    sendData.append(0x78);                             //功能碼
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    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);                    //開啟延時(shí)低位
    sendData.append(deltime / 256);                    //開啟延時(shí)高位
 
    SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
}
 
//驅(qū)動設(shè)備關(guān)閉繼電器----------------------------------------------------------------------------------------------------------
void MainWindow::on_PBSwitchOff_clicked()
{
    sendData.clear();
    sendData.append(0x78);                             //功能碼
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    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);                    //延時(shí)低位
    sendData.append(deltime / 256);                    //延時(shí)高位
 
    SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
}
 
//驅(qū)動設(shè)備顯示文字+蜂鳴響聲+播報(bào)TTS語音+開啟繼電器開關(guān)------------------------------------------------------------------------------
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語音轉(zhuǎn)換為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);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    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);                    //延時(shí)低位
    sendData.append(deltime / 256);                    //延時(shí)高位
 
    sendData.append(ui->spinBox_dispdelay->value());   //文字顯示時(shí)長,
    quint8 begindisp =0;                               //在顯示屏中的哪個(gè)位置開始顯示,一般取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;itextEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    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);                    //延時(shí)低位
    sendData.append(deltime / 256);                    //延時(shí)高位
 
    sendData.append(ui->spinBox_dispdelay->value());   //文字顯示時(shí)長,
 
    sendData.append(begindisp);                        //顯示起始位置
    sendData.append(dispbytes);                        //顯示字符串長度
    sendData.append(lensy);                            //語音代碼條數(shù)
 
    QString dispstr=ui->textEdit_disp->toPlainText()+"                                  ";  //加空格是為了確保滿屏34位顯示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;itextEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感應(yīng)區(qū)內(nèi)任意卡,如要操作特定卡可指定卡號
    cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf);
    if(cardnolentextEdit_M1UID->setFocus();
        return;
    }
 
    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=MyClass::checkhexdata(keyinf,keybuf);
    if(keylentextEdit_authkey->setFocus();
        return;
    }
 
    sendData.clear();
    sendData.append(0x3b);                             //功能碼
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(0x01);                             //本次操作的區(qū)數(shù)
    for (int i=0 ;iCBPage->currentIndex());       //本次操作的扇區(qū)號
    sendData.append(ui->CBauth->currentIndex());       //為1以B密碼來驗(yàn)證舊密碼,為0以A密碼來驗(yàn)證舊密碼
    for (int i=0 ;itextEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感應(yīng)區(qū)內(nèi)任意卡,如要操作特定卡可指定卡號
    cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf);
    if(cardnolentextEdit_M1UID->setFocus();
        return;
    }
 
    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=MyClass::checkhexdata(keyinf,keybuf);
    if(keylentextEdit_authkey->setFocus();
        return;
    }
 
    QString datastr = ui->textEdit_data->toPlainText().trimmed();
    datastr=datastr.replace(" ","");
    datalen=MyClass::checkhexdata(datastr,writecardbuf);
    if(datalentextEdit_data->setFocus();
            return;
        }
        for (int i=datalen;i48){
            int answ=QMessageBox::question (this, "警告", "本指令只可以寫一個(gè)扇區(qū)數(shù)據(jù),是否將前48個(gè)數(shù)據(jù)寫入到指定扇區(qū)?", 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);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(0x01);                             //本次操作的區(qū)數(shù)
    for (int i=0 ;iCBPage->currentIndex());       //本次操作的扇區(qū)號
    sendData.append(ui->CBauth->currentIndex());       //為1以B密碼來驗(yàn)證舊密碼,為0以A密碼來驗(yàn)證舊密碼
    for (int i=0 ;itextEdit_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"表示可能操作感應(yīng)區(qū)內(nèi)任意卡,如要操作特定卡可指定卡號
    cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf);
    if(cardnolentextEdit_M1UID->setFocus();
        return;
    }
 
    QString keyinf = ui->textEdit_authkey->toPlainText().trimmed();
    keylen=MyClass::checkhexdata(keyinf,keybuf);
    if(keylentextEdit_authkey->setFocus();
        return;
    }
 
    QString newkey = ui->textEdit_newkey->toPlainText().trimmed();
    newkeylen=MyClass::checkhexdata(newkey,newkeybuf);
    if(newkeylentextEdit_newkey->setFocus();
        return;
    }
 
    sendData.clear();
    sendData.append(0x3a);                             //功能碼
    quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt();
    sendData.append(devno % 256);                      //機(jī)號低位
    sendData.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(0x01);                             //本次操作的區(qū)數(shù)
    for (int i=0 ;iCBPage->currentIndex());       //本次操作的扇區(qū)號
    quint8 auth=ui->CBauth->currentIndex();            //為1以B密碼來驗(yàn)證舊密碼,為0以A密碼來驗(yàn)證舊密碼
    auth=auth+ui->ChangeKey->currentIndex()*2;         //修改A、B、控制位
    sendData.append(auth);
 
    for (int i=0 ;iscrollArea->setVisible(false);
    ui->scrollArea_wifi->setVisible(false);
    ui->scrollArea_config->setVisible(true);
}
 
 
void MainWindow::on_PBcopylist_clicked()
{
    QString listinf;
    int row=ui->listWidget->count();
    if (rowlistWidget->item(i);
            listinf=listinf+item->text()+"n";
        }
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(listinf);
        QMessageBox::information(this, "提示", "顯示數(shù)據(jù)報(bào)文已拷貝到剪切板");
    }
}
 
//接收到刷卡數(shù)據(jù)立即回應(yīng)--------------------------------------------------------------------------
void MainWindow::Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber)
{
    QByteArray RespBuff;
    RespBuff.append(0x5A);                             //功能碼
    quint16 devno=DeviceNumber.toUInt();
    RespBuff.append(devno % 256);                      //機(jī)號低位
    RespBuff.append(devno / 256);                      //機(jī)號高位,高低位都為0表示所有機(jī)
    RespBuff.append(ui->CBbeep->currentIndex());       //蜂鳴響聲代碼,255表示不響聲
    RespBuff.append(ui->spinBox_dispdelay->value());   //文字顯示時(shí)長,
    QString dispstr=Dispinf+"                                  ";  //加空格是為了確保滿屏34位顯示
    QByteArray Dispbyte=dispstr.toLocal8Bit();
    for(int i=0;iwriteDatagram(RespBuff.constData(), RespBuff.size(), QHostAddress(ip), port);
 
    QString SendHex=MyClass::getsystime()+" Send To: "+(ip.toString()+":"+QString::asprintf("%d",port)+"             ").mid(0,22);
    SendHex=SendHex+MyClass::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=MyClass::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=MyClass::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 (!MyClass::isValidIP(newip)){
        QMessageBox::critical(NULL, "提示", "請輸入有效的設(shè)備IP!");
        ui->New_IP->setFocus();
        return;
    }
    QString newmask=ui->New_Mask->text().trimmed();
    if (!MyClass::isValidIP(newmask)){
        QMessageBox::critical(NULL, "提示", "請輸入有效的設(shè)備掩碼!");
        ui->New_Mask->setFocus();
        return;
    }
    QString newserverip=ui->New_ServerIP->text().trimmed();
    if (!MyClass::isValidIP(newserverip)){
        QMessageBox::critical(NULL, "提示", "請輸入有效的遠(yuǎn)程服務(wù)器ip!");
        ui->New_ServerIP->setFocus();
        return;
    }
    QString newgateway=ui->New_Gateway->text().trimmed();
    if (!MyClass::isValidIP(newgateway)){
        QMessageBox::critical(NULL, "提示", "請輸入有效的網(wǎng)關(guān)!");
        ui->New_Gateway->setFocus();
        return;
    }
    QString servermac=ui->ServerMAC->text().trimmed();
    if (!MyClass::isValidMac(servermac)){
        QMessageBox::critical(NULL, "提示", "請輸入有效的遠(yuǎn)程服務(wù)器MAC!");
        ui->ServerMAC->setFocus();
        return;
    }
    QString gatemac=ui->GateWayMac->text().trimmed();
    if (!MyClass::isValidMac(gatemac)){
        QMessageBox::critical(NULL, "提示", "請輸入有效的網(wǎng)關(guān)MAC!");
        ui->GateWayMac->setFocus();
        return;
    }
    bool ok;
    sendData.clear();
    sendData.append(0xf9);                   //功能碼
    QStringList liststr = newip.split(".");  //新IP
    for (int i=0 ;iNew_Nember->text().toUInt();
    sendData.append(devno % 256);           //機(jī)號低位
    sendData.append(devno / 256);           //機(jī)號高位,高低位都為0表示所有機(jī)
 
    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 ;icheckBox_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()){   //使用廣播方式發(fā)送指令
        QHostAddress broadcastAddress("255.255.255.255");
        quint16 port1 = 39169;
        udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);
        QString  dispinf=MyClass::getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22) ;
        dispinf=dispinf+MyClass::ByteArrayToHexString(sendData);
        listadditems(0,dispinf);
    }else{
        SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
    }
}
 
 
void MainWindow::on_pushButton_SetTCP_clicked()
{
    sendData.clear();
    sendData.append(0x1d);                  //功能碼
    quint16 devno=0;                        //機(jī)號,0表示所有機(jī)
    sendData.append(devno % 256);           //機(jī)號低位
    sendData.append(devno / 256);           //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(7);                     //指令長度
    sendData.append(0x5c);                  //修改TCP通訊端口功能碼
    sendData.append(4);                     //數(shù)據(jù)長度
 
    quint16 devport=ui->New_Port->text().toUInt(); //讀卡器端口
    sendData.append(devport % 256);           //低位
    sendData.append(devport / 256);           //高位
 
    quint16 serverport=ui->lineEdit_TCPRemoPort->text().toUInt(); //遠(yuǎn)程TCP服務(wù)器端口
    sendData.append(serverport % 256);        //低位
    sendData.append(serverport / 256);        //高位
 
    quint8 crc=sendData[6]^sendData[7]^sendData[8]^sendData[9];    //數(shù)據(jù)校驗(yàn)位
    sendData.append(crc);
 
    sendData.append(0x55);      //防干擾后綴
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);
 
    if (ui->checkBox_broadcast->isChecked()){   //使用廣播方式發(fā)送指令
        QHostAddress broadcastAddress("255.255.255.255");
        quint16 port1 = 39169;
        udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);
        QString  dispinf=MyClass::getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22) ;
        dispinf=dispinf+MyClass::ByteArrayToHexString(sendData);
        listadditems(0,dispinf);
    }else{
        SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
    }
}
 
 
void MainWindow::on_pushButton_SetHttp_clicked()
{
    QString filenamestr=ui->lineEdit_filename->text().trimmed();
    QByteArray filebyte=filenamestr.toLocal8Bit();
    if(filebyte.size()lineEdit_filename->setFocus();
        return;
    }
    sendData.clear();
    sendData.append(0x1d);                  //功能碼
    quint16 devno=0;                        //機(jī)號,0表示所有機(jī)
    sendData.append(devno % 256);           //機(jī)號低位
    sendData.append(devno / 256);           //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(filebyte.size()+7);     //指令長度
    sendData.append(0x5b);                  //設(shè)置http協(xié)議讀卡器訪問文件、端口、提效方式的識別碼
    sendData.append(filebyte.size()+4);     //數(shù)據(jù)長度
    sendData.append(ui->comboBox_Sendmodel->currentIndex()); //提交方式
    sendData.append(0xff);
 
    quint16 serverport=ui->lineEdit_HttpRemoPort->text().toUInt(); //遠(yuǎn)程http服務(wù)器端口
    sendData.append(serverport % 256);        //低位
    sendData.append(serverport / 256);        //高位
 
    quint8 crc= sendData[6]^ sendData[7]^ sendData[8]^sendData[9];
 
    for(int i=0;icheckBox_broadcast->isChecked()){   //使用廣播方式發(fā)送指令
        QHostAddress broadcastAddress("255.255.255.255");
        quint16 port1 = 39169;
        udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1);
        QString  dispinf=MyClass::getsystime()+" Send To: "+("255.255.255.255:"+QString::number(port1)+"             ").mid(0,22) ;
        dispinf=dispinf+MyClass::ByteArrayToHexString(sendData);
        listadditems(0,dispinf);
    }else{
        SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
    }
}
 
 
void MainWindow::on_pushButton_16_clicked()
{
    ui->scrollArea_wifi->setVisible(false);
}
 
 
void MainWindow::on_PBClear_2_clicked()
{
    int currentRow = ui->tableWidget->currentIndex().row();
    if (currentRowscrollArea->setVisible(false);
        ui->scrollArea_wifi->setVisible(true);
        ui->scrollArea_config->setVisible(false);
    }
}
 
 
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()60){
        QMessageBox::critical(NULL, "提示", "WIFI熱點(diǎn)名稱長度不可大于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;                        //機(jī)號,0表示所有機(jī)
    sendData.append(devno % 256);           //機(jī)號低位
    sendData.append(devno / 256);           //機(jī)號高位,高低位都為0表示所有機(jī)
    sendData.append(wifiNamearry.size());   //熱點(diǎn)名稱長度
    quint8 passlen=0;
    if(ui->checkBox_wifikey->isChecked()){
        passlen=wifipassarry.size();
    }
    sendData.append(passlen);                //密碼長度
 
    int i=0;
    for (i=0;iradioButton_IP->isChecked()){
        sendData.append(1);
        QString ipstr=ui->lineEdit_IP->text().trimmed();
        if (!MyClass::isValidIP(ipstr)){
            QMessageBox::critical(NULL, "提示", "請輸入有效的設(shè)備IP!");
            ui->lineEdit_IP->setFocus();
            return;
        }
        QString mskstr=ui->lineEdit_mask->text().trimmed();
        if (!MyClass::isValidIP(mskstr)){
            QMessageBox::critical(NULL, "提示", "請輸入正確的讀卡器子網(wǎng)掩碼!");
            ui->lineEdit_mask->setFocus();
            return;
        }
        QString gatewaystr=ui->lineEdit_gateway->text().trimmed();
        if (!MyClass::isValidIP(gatewaystr)){
            QMessageBox::critical(NULL, "提示", "請輸入正確的讀卡器網(wǎng)關(guān)!");
            ui->lineEdit_mask->setFocus();
            return;
        }
        QStringList liststr = ipstr.split(".");  //IP
        for (int i=0 ;icomboBox_Sendmode->currentIndex());
 
    sendData.append(0x55);      //防干擾后綴
    sendData.append(0xaa);
    sendData.append(0x66);
    sendData.append(0x99);
    SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備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);           //機(jī)號低位
    sendData.append(devno / 256);           //機(jī)號高位,高低位都為0表示所有機(jī)
    SendBuffAct();        //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口
}
 
 
void MainWindow::on_PBTcpServer_clicked()
{
    this->tcpserverwin=new TcpServerWin;
    //tcpserverwin->setWindowFlag(Qt::WindowStaysOnTopHint, true);    //UI窗口置頂顯示
    tcpserverwin->show();
}
 
 
void MainWindow::on_pushButton_close2_clicked()
{
    ui->scrollArea_config->setVisible(false);
}
 
//
void MainWindow::on_pushButton_SetConfig_clicked()
{
    unsigned char sendbuff[134];
    sendbuff[0]=0x4b;       //功能碼
    sendbuff[1]=0x00;       //2字節(jié)機(jī)號都取0表示任意機(jī)
    sendbuff[2]=0x00;
    sendbuff[3]=0x00;       //主動讀卡的扇區(qū)數(shù)量
    int j=4;
    for(int i=0;ifindChild("checkBox_s"+QString::asprintf("%d",i));
        QComboBox *myComboBox = this->findChild("CBauth_"+QString::asprintf("%d",i));
        QTextEdit *myTextEdit = this->findChild("textEdit_key_"+QString::asprintf("%d",i));
 
        unsigned char keybuf[6];         //密鑰
        if (myCheckBox->isChecked()) {
            QString keyinf =myTextEdit->toPlainText().trimmed();
            int keylen=MyClass::checkhexdata(keyinf,keybuf);
            if(keylensetFocus();
                return;
            }
            sendbuff[3]=sendbuff[3]+1;         //主動讀卡的扇區(qū)數(shù)量加1
            sendbuff[j]=i;                     //扇區(qū)號
            if(myComboBox->currentIndex()>0){
                sendbuff[j]=sendbuff[j] | 128; //密鑰認(rèn)證方式
            }
            for(int p=0;plabel_msg_2->setText("設(shè)置主動讀卡扇區(qū)及認(rèn)證密鑰的指令已發(fā)送...");
}
 
 
void MainWindow::on_PBwritecard_clicked()
{
    int currentRow = ui->tableWidget->currentIndex().row();
    if (currentRowtextEdit_data->toPlainText().trimmed();
        writehex=writehex.replace(" ","");
        int j=MyClass::checkhexdata(writehex,writecardbuf);
        if((j0){
            sendData.clear();
            sendData.append(0x3c);           //功能碼
            quint16 devno=0;
            sendData.append(devno % 256);    //機(jī)號低位
            sendData.append(devno / 256);    //機(jī)號高位,高低位都為0表示所有機(jī)
            sendData.append(writcarepoi);    //當(dāng)前已寫扇區(qū)指針
 
            j=writcardlen - writcarepoi;
            if(j>4){j=4;};
            sendData.append(j);              //本次總計(jì)寫扇區(qū)數(shù),一次最多寫4扇區(qū),多于4扇區(qū)要分次寫入
 
            for (int i=0;i

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • IC卡
    +關(guān)注

    關(guān)注

    2

    文章

    168

    瀏覽量

    34149
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1370

    瀏覽量

    79133
  • Qt
    Qt
    +關(guān)注

    關(guān)注

    1

    文章

    306

    瀏覽量

    37958
收藏 人收藏

    評論

    相關(guān)推薦

    ID卡網(wǎng)絡(luò)讀卡器C#小程序開發(fā)

    (85.6x54x0.80±0.04mm)、異型卡等不同類型。按照應(yīng)用場景,它通常包含個(gè)人的身份信息,如姓名、照片、身份證號碼等,常見的包括身份證、員工工作證、學(xué)生證,以及用于考勤、門禁、一卡通等系統(tǒng)的卡片。 二、工作原理 ID卡的工作過程如下: ID卡閱讀
    的頭像 發(fā)表于 12-31 11:30 ?69次閱讀
    <b class='flag-5'>ID</b>卡網(wǎng)絡(luò)<b class='flag-5'>讀卡器</b>C#小<b class='flag-5'>程序</b><b class='flag-5'>開發(fā)</b>

    網(wǎng)絡(luò)讀卡器qt代碼示例

    buflen) { DisableSendAgain(ip, port,databuff,buflen);//確認(rèn)接收到的信息,否則同一信息讀卡器會重發(fā)三次 QString IPAddress
    發(fā)表于 12-30 10:22

    開疆智能Modbus轉(zhuǎn)Profinet網(wǎng)關(guān)連接Modbus讀卡器YW-630MA配置案例

    簡介: Modbus讀卡器YW-630MA是基于RS485總線,遵循Modbus RTU協(xié)議的一款I(lǐng)C卡讀卡器.。這款讀卡器使為PLC而設(shè)計(jì)和研發(fā)的新一代讀寫
    的頭像 發(fā)表于 12-23 09:41 ?119次閱讀
    開疆智能Modbus轉(zhuǎn)Profinet網(wǎng)關(guān)連接Modbus<b class='flag-5'>讀卡器</b>YW-630MA配置案例

    什么是socket編程 socket與tcp/ip協(xié)議的關(guān)系

    基于TCP/IP協(xié)議族,這是一組用于網(wǎng)絡(luò)通信的協(xié)議,包括傳輸控制協(xié)議TCP)和互聯(lián)網(wǎng)協(xié)議(IP
    的頭像 發(fā)表于 11-01 16:01 ?381次閱讀

    充電樁非接觸式讀卡器 FSV-MD5422-01

    1、簡介 FSV-MD5422-01?產(chǎn)品是一款基于?13.56MHZ?頻率射頻技術(shù)上開發(fā)出來的非接觸式讀卡器模塊,?產(chǎn)品基于?TTL、RS232?串口兩種設(shè)計(jì)接口,通信協(xié)議簡單實(shí)用,方便產(chǎn)品
    的頭像 發(fā)表于 10-29 10:27 ?228次閱讀
    充電樁非接觸式<b class='flag-5'>讀卡器</b> FSV-MD5422-01

    TRF7970A NFC讀卡器天線多路復(fù)用

    電子發(fā)燒友網(wǎng)站提供《TRF7970A NFC讀卡器天線多路復(fù)用.pdf》資料免費(fèi)下載
    發(fā)表于 10-26 11:15 ?0次下載
    TRF7970A NFC<b class='flag-5'>讀卡器</b>天線多路復(fù)用

    AGV讀卡器在AGV自動搬運(yùn)小車上應(yīng)用方案

    AGV小車上的AGV讀卡器通過讀取地面軌道的RFID電子標(biāo)簽信息,做出相應(yīng)的動作(如改變速度、選擇軌道、定位和停車等)。在AGV小車經(jīng)過站點(diǎn)A處時(shí),AGV讀卡器讀取A處的電子標(biāo)簽ID號,AGV小車
    的頭像 發(fā)表于 10-12 17:33 ?262次閱讀
    AGV<b class='flag-5'>讀卡器</b>在AGV自動搬運(yùn)小車上應(yīng)用方案

    二代身份證識別儀身份證閱讀讀卡器

    掃描儀 工地實(shí)名制讀卡器 二代證閱讀 ID/IC讀卡器 NFC讀卡模塊 多合一身份證讀卡模塊
    發(fā)表于 09-07 15:09

    X-CUBE-NFC4能否用于其他品牌的NFC讀卡器?

    X-CUBE-NFC4能否用于其他品牌的NFC讀卡器,或者通過移植來驅(qū)動其他品牌的NFC讀卡器
    發(fā)表于 05-22 06:27

    網(wǎng)絡(luò)讀卡器_產(chǎn)品手冊

    電子發(fā)燒友網(wǎng)站提供《網(wǎng)絡(luò)讀卡器_產(chǎn)品手冊.pdf》資料免費(fèi)下載
    發(fā)表于 05-19 09:33 ?0次下載

    IO-Link RFID讀卡器系統(tǒng)方案設(shè)計(jì)與挑戰(zhàn)

    如圖2這個(gè)IO-Link RFID傳感的方案,使用了L6364和STM32G0通用電路來支持IO-Link的協(xié)議轉(zhuǎn)換,使用ST25R3916來作為NFC的讀卡器芯片。
    發(fā)表于 04-02 10:56 ?665次閱讀
    IO-Link RFID<b class='flag-5'>讀卡器</b>系統(tǒng)方案設(shè)計(jì)與挑戰(zhàn)

    Qt上位機(jī)開發(fā)實(shí)戰(zhàn)案例

    Qt框架的開發(fā)人員能迅速上手和操作。 即使不開發(fā)Qt應(yīng)用程序,Qt Creator也是一個(gè)
    的頭像 發(fā)表于 03-13 12:31 ?2617次閱讀
    <b class='flag-5'>Qt</b>上位機(jī)<b class='flag-5'>開發(fā)</b>實(shí)戰(zhàn)案例

    如何基于EsDA開發(fā)套件快速使用射頻讀卡器模塊

    無線射頻讀寫卡技術(shù)在門禁系統(tǒng),電子支付領(lǐng)域和物聯(lián)網(wǎng)等領(lǐng)域中具有越來越廣泛的應(yīng)用。本文將基于EsDA開發(fā)套件講解如何快速上手并開發(fā)射頻讀卡器模塊的相關(guān)業(yè)務(wù),為開發(fā)者大大縮短了學(xué)習(xí)和
    的頭像 發(fā)表于 01-11 08:24 ?725次閱讀
    如何基于EsDA<b class='flag-5'>開發(fā)</b>套件快速使用射頻<b class='flag-5'>讀卡器</b>模塊