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ā)揮著重要作用。
QT開發(fā)示例的UI界面如下:
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()1){ QMessageBox::information(NULL, "提示", "未搜索到本機(jī)的網(wǎng)卡,系統(tǒng)不能正常運(yùn)行!"); delete ui; } sockinit(); } MainWindow::~MainWindow() { delete ui; } //通訊報(bào)文顯示----------------------------------------------------------------------------------------------------- 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); } } //廣播發(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;i9;i++){ sendData.append(databuff[i]); SendHex=SendHex+QString::asprintf("%02X ", databuff[i]); } udpSocket-?>writeDatagram(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;i16;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); } int j=databuff[10]*48; int m=databuff[11]*48; for(int i=0;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;i4;i++){ //加入4個(gè)字節(jié)的卡號,卡號為0表示可以操作任意卡 RespBuff.append(1-1); } 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;i12;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); } QString Sector=QString::asprintf("%d", databuff[12]); //扇區(qū)號 DispInf="讀取M1卡"+Sector+"扇區(qū)數(shù)據(jù)"; switch (databuff[13]){ case 0: { QString DataHex=""; for (int i=0;i48;i++){ DataHex=DataHex+QString::asprintf("%02X ", databuff[14+i]); } DispInf=DispInf+"成功,設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",16進(jìn)制卡號:"+CardnoHex; ui-?>textEdit_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;i13;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); //16進(jìn)制卡號 } QString Sector=QString::asprintf("%d", databuff[13]); //扇區(qū)號 QString Pages=QString::asprintf("%d", databuff[8]); //本次操作的扇區(qū)總數(shù) QString DispInf=""; if(databuff[1]==0x3a){ DispInf="修改M1卡"+Sector+"扇區(qū)密鑰"; }else if(databuff[1]==0x3d){ DispInf="寫數(shù)據(jù)到M1卡"+Sector+"扇區(qū)"; } switch (databuff[14]){ case 0: DispInf=DispInf+"成功,設(shè)備IP:"+IPAddress+",機(jī)號:"+DeviceNumber+",16進(jìn)制卡號:"+CardnoHex; 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); if(ui-?>checkBox_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 (currentRow0){ QMessageBox::critical(this, "警告", "請選擇一臺在線設(shè)備再執(zhí)行此功能!", QMessageBox::Ok); }else{ ui-?>scrollArea_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;i34;i++){ sendData.append(Dispbyte[i]); } SendBuffAct(); //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口 } //驅(qū)動設(shè)備蜂鳴響聲----------------------------------------------------------------------------------------------------------- void MainWindow::on_PBbeep_clicked() { sendData.clear(); sendData.append(0x96); //功能碼 quint16 devno=ui-?>textEdit_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(cardnolen4){ QMessageBox::critical(NULL, "提示", "請輸入8位正確的16進(jìn)制卡號!"); ui-?>textEdit_M1UID->setFocus(); return; } QString keyinf = ui->textEdit_authkey->toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進(jìn)制卡密碼!"); ui-?>textEdit_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 ;i4;i++){ //指定讀寫的卡號,全為0 表示可讀寫任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui-?>CBPage->currentIndex()); //本次操作的扇區(qū)號 sendData.append(ui->CBauth->currentIndex()); //為1以B密碼來驗(yàn)證舊密碼,為0以A密碼來驗(yàn)證舊密碼 for (int i=0 ;i6;i++){ sendData.append(keybuf[i]); //認(rèn)證密鑰 } SendBuffAct(); //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口 } //指定扇區(qū)密鑰寫入數(shù)據(jù)到M1卡扇區(qū)---------------------------------------------------------------------------------------- void MainWindow::on_PBWriteCard_clicked() { unsigned char cardnobuf[4]; //卡號 unsigned char keybuf[6]; //密鑰 int keylen; int cardnolen; int datalen; QString cardnostr ="00000000"; // ui-?>textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感應(yīng)區(qū)內(nèi)任意卡,如要操作特定卡可指定卡號 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen4){ QMessageBox::critical(NULL, "提示", "請輸入8位正確的16進(jìn)制卡號!"); ui-?>textEdit_M1UID->setFocus(); return; } QString keyinf = ui->textEdit_authkey->toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進(jìn)制卡密碼!"); ui-?>textEdit_authkey->setFocus(); return; } QString datastr = ui->textEdit_data->toPlainText().trimmed(); datastr=datastr.replace(" ",""); datalen=MyClass::checkhexdata(datastr,writecardbuf); if(datalen48){ int answ=QMessageBox::question (this, "警告", "有效的寫卡數(shù)據(jù)不足一扇區(qū)48字節(jié),是否要補(bǔ)0寫入到指定扇區(qū)?", QMessageBox::Ok, QMessageBox::Cancel); if (answ !=1024){ ui-?>textEdit_data->setFocus(); return; } for (int i=datalen;i48;i++){ writecardbuf[i]=0; } }else { if (datalen?>48){ 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 ;i4;i++){ //指定讀寫的卡號,全為0 表示可讀寫任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui-?>CBPage->currentIndex()); //本次操作的扇區(qū)號 sendData.append(ui->CBauth->currentIndex()); //為1以B密碼來驗(yàn)證舊密碼,為0以A密碼來驗(yàn)證舊密碼 for (int i=0 ;i6;i++){ sendData.append(keybuf[i]); //認(rèn)證密鑰 } for (int i=0 ;i48;i++){ sendData.append(writecardbuf[i]); //寫卡數(shù)據(jù) } sendData.append(0x55); //防干擾后綴 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口 } //修改M1卡扇區(qū)密鑰------------------------------------------------------------------------------------------------- void MainWindow::on_PBChangeKey_clicked() { int answ=QMessageBox::question (this, "警告", "執(zhí)行此操作前請記住卡片新密鑰,否則卡片將報(bào)廢!是否繼續(xù)?", 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"表示可能操作感應(yīng)區(qū)內(nèi)任意卡,如要操作特定卡可指定卡號 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen4){ QMessageBox::critical(NULL, "提示", "請輸入8位正確的16進(jìn)制卡號!"); ui-?>textEdit_M1UID->setFocus(); return; } QString keyinf = ui->textEdit_authkey->toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進(jìn)制卡密碼!"); ui-?>textEdit_authkey->setFocus(); return; } QString newkey = ui->textEdit_newkey->toPlainText().trimmed(); newkeylen=MyClass::checkhexdata(newkey,newkeybuf); if(newkeylen16){ QMessageBox::critical(NULL, "提示", "請輸16進(jìn)制 6字節(jié)A密碼+4字節(jié)控制位+6字節(jié)B密碼 !"); ui-?>textEdit_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 ;i4;i++){ //指定讀寫的卡號,全為0 表示可讀寫任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui-?>CBPage->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 ;i6;i++){ sendData.append(keybuf[i]); //認(rèn)證密鑰 } for (int i=0 ;i16;i++){ sendData.append(newkeybuf[i]); //新A密鑰、控制位、B密鑰 } sendData.append(0x55); //防干擾后綴 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口 } void MainWindow::on_PBSetRW_clicked() { ui-?>scrollArea->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 (row1){ return; }else{ for (int i=0;ilistWidget->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;i34;i++){ RespBuff.append(Dispbyte[i]); } udpSocket-?>writeDatagram(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 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = newmask.split("."); //掩碼 for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = newserverip.split("."); //遠(yuǎn)程服務(wù)器IP for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = servermac.split("-"); //遠(yuǎn)程服務(wù)器MAC for (int i=0 ;i6;i++){ sendData.append(liststr[i].toInt(&ok,16)); } liststr = newgateway.split("."); //網(wǎng)關(guān) for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = gatemac.split("-"); //網(wǎng)關(guān)MAC for (int i=0 ;i6;i++){ sendData.append(liststr[i].toInt(&ok,16)); } quint16 devno=ui-?>New_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 ;i4;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()){ //使用廣播方式發(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()1){ QMessageBox::critical(NULL, "提示", "請輸入正確的訪問文件,可以是.asp\.jsp\.php等腳本文件!"); ui-?>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 (currentRow0){ QMessageBox::critical(this, "警告", "請選擇一臺在線設(shè)備再執(zhí)行此功能!", QMessageBox::Ok); }else{ ui-?>scrollArea->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()1 || 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 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = mskstr.split("."); //掩碼 for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = gatewaystr.split("."); //網(wǎng)關(guān) for (int i=0 ;i4;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緩沖數(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;i16;i++){ QCheckBox *myCheckBox = this-?>findChild("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(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進(jìn)制卡密碼!"); myTextEdit-?>setFocus(); 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;p6;p++){ //認(rèn)證密鑰 j=j+1; sendbuff[j]=keybuf[p]; } j=j+1; } } int qhzs=sendbuff[3]; sendbuff[4+qhzs*7]=0x55; //抗干擾后綴 sendbuff[5+qhzs*7]=0xaa; sendbuff[6+qhzs*7]=0x66; sendbuff[7+qhzs*7]=0x99; sendData.clear(); for(int i=0;i<=7+qhzs*7;i++){ sendData.append(sendbuff[i]); } SendBuffAct(); //將sendData緩沖數(shù)據(jù)發(fā)送到指定的設(shè)備IP端口 ui-?>label_msg_2->setText("設(shè)置主動讀卡扇區(qū)及認(rèn)證密鑰的指令已發(fā)送..."); } void MainWindow::on_PBwritecard_clicked() { int currentRow = ui->tableWidget->currentIndex().row(); if (currentRow0){ QMessageBox::critical(this, "警告", "請選擇一臺在線設(shè)備再執(zhí)行此功能!", QMessageBox::Ok); }else{ QString writehex = ui-?>textEdit_data->toPlainText().trimmed(); writehex=writehex.replace(" ",""); int j=MyClass::checkhexdata(writehex,writecardbuf); if((j1) || (j%48 !=0) ){ QMessageBox::critical (this, "警告", "寫卡數(shù)據(jù)輸入錯(cuò)誤,入寫卡字節(jié)數(shù)必須為 48 的倍數(shù)的16進(jìn)制數(shù)據(jù)!", QMessageBox::Ok); return; } writcardlen=j/48; writcarepoi=0; if(writcardlen?>0){ 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;i4;i++){ //加入4個(gè)字節(jié)的卡號,卡號為0表示可以操作任意卡 sendData.append(1-1); } for (int i=0;i
-
IC卡
+關(guān)注
關(guān)注
2文章
168瀏覽量
34149 -
TCP
+關(guān)注
關(guān)注
8文章
1370瀏覽量
79133 -
Qt
+關(guān)注
關(guān)注
1文章
306瀏覽量
37958
發(fā)布評論請先 登錄
相關(guān)推薦
評論