ID卡網絡讀卡器TCP協議QT小程序開發。
TCP(傳輸控制協議,Transmission Control Protocol)是互聯網中最核心、最基本的協議之一。以下是對TCP協議的詳細介紹:
一、基本概念
TCP是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。它工作在OSI模型的第四層,即傳輸層,為用戶提供可靠的、有序的和無差錯的數據傳輸服務。TCP協議與UDP協議是傳輸層的兩大主要協議,但兩者在設計上有明顯的不同:TCP提供的是可靠的數據傳輸服務,而UDP則更注重傳輸的速度和效率。
二、技術特點
1.面向連接:TCP在傳輸數據之前,必須先建立連接,確保數據的傳輸路徑是可靠的。連接建立后,TCP會維護一個連接狀態,包括序列號、窗口大小等信息,用于保證數據傳輸的有序性和可靠性。
2.可靠傳輸:TCP通過確認重傳機制、滑動窗口機制、超時重傳機制等方式,確保數據在傳輸過程中不會丟失、不會重復、不會亂序。具體來說,TCP會給每個報文段分配一個序列號,接收方根據序列號確認數據的順序和完整性。如果接收方發現數據丟失或亂序,會要求發送方重傳。
3.字節流傳輸:TCP將應用層發送的數據劃分成以字節為單位的報文段,并進行序列號標記。這種方式能夠確保數據在傳輸過程中不會被拆分或丟失,從而保證數據的完整性。
4.全雙工通信:TCP允許雙方在任何時候都能發送數據,為此TCP連接的兩端都設有發送緩存和接收緩存,用來臨時存放雙向通信的數據。
三、工作原理
1.連接建立:TCP連接建立采用三次握手過程。首先,客戶端向服務器發送一個SYN報文段,請求建立連接。服務器收到后,回復一個SYN-ACK報文段,表示同意建立連接并確認客戶端的SYN報文段。最后,客戶端再發送一個ACK報文段,確認服務器的SYN-ACK報文段。至此,TCP連接建立完成。
2.數據傳輸:在連接建立后,雙方可以開始傳輸數據。TCP會將應用層發送的數據劃分成報文段,并添加TCP頭部信息(包括序列號、窗口大小等),然后交給IP層進行傳輸。接收方收到報文段后,會進行校驗和檢查、序列號確認等操作,確保數據的完整性和順序性。如果發現問題,會要求發送方重傳。
3.連接終止:TCP連接終止采用四次揮手過程。首先,一方發送一個FIN報文段,表示要關閉連接。另一方收到后,回復一個ACK報文段,表示同意關閉連接但還有數據要發送。當所有數據發送完畢后,另一方再發送一個FIN報文段,表示關閉連接。最后,接收方回復一個ACK報文段,確認連接關閉。至此,TCP連接終止完成。
四、應用場景
TCP協議廣泛應用于需要可靠傳輸的場合,如HTTP、FTP等協議都基于TCP協議進行數據傳輸。此外,TCP還用于數據庫連接、遠程登錄等需要穩定連接的場合。
綜上所述,TCP協議是一種高效、穩定且可靠的傳輸層協議,它通過多種機制確保數據的可靠傳輸和有序性。在互聯網傳輸中,TCP協議發揮著重要作用。
QT開發示例的UI界面如下:
mainWindow.cpp代碼如下:
bool listening=false; //sock偵聽標志 QByteArray sendData; //發送數據緩沖 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, "提示", "未搜索到本機的網卡,系統不能正常運行!"); delete ui; } sockinit(); } MainWindow::~MainWindow() { delete ui; } //通訊報文顯示----------------------------------------------------------------------------------------------------- void MainWindow::listadditems(int ctr,QString listinfo){ switch (ctr){ case 0: if(ui-?>listWidget->count()>10){ ui->listWidget->clear(); } ui->listWidget->addItem(listinfo); ui->listWidget->setCurrentRow(ui->listWidget->count()-1); break; case 1: ui->textEdit_msg->setText(listinfo); } } //廣播發送搜索所有在線的設備------------------------------------------------------------------------------------------- void MainWindow::on_PBSearch_clicked() { int n = ui->tableWidget->rowCount();//總行數 for (int i = 0;i <= n;i++) ui-?>tableWidget->removeRow(0);//遍歷刪除第0行 QHostAddress broadcastAddress("255.255.255.255"); quint16 port1 = 39169; sendData.clear(); sendData.append(0xA6); udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1); //搜索所有在線設備 QString dispinf=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); //查詢在線設備型號、固件日期 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); 這個方式是綁定所有網卡,這樣發不出廣播包 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偵聽已關閉!"); } } //Socket UDP端口接收數據--------------------------------------------------------------------------------------------------------- void MainWindow::read_data(){ unsigned char databuff[1024] = {0}; QHostAddress ip; quint16 port; qint64 buflen = udpSocket->readDatagram((char *)databuff, sizeof(databuff), &ip, &port); QString str; for (int i = 0; i < buflen; i++) { str +=QString::asprintf("%02X ", databuff[i]); } QString dispinf=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卡扇區數據的返回 break; case 0x3c: Analyze_3c(ip, port,databuff,buflen); //主動寫M1卡扇區數據的返回 break; case 0xc5: Analyze_c5(ip, port,databuff,buflen); //指定區號密鑰讀取M1扇區數據返回 break; case 0xcd: Analyze_cd(ip, port,databuff,buflen); //指定區號密鑰寫數據到M1卡扇區返回 break; case 0xd1: Analyze_d1(ip, port,databuff,buflen); //解析讀取ID卡卡號 break; case 0xcf: case 0xdf: Analyze_cf_df(ip, port,databuff,buflen); //解析IC、ID卡離開讀卡器 break; case 0xf2: Analyze_f2(ip, port,databuff,buflen); //在線設備響應搜索指令的返回、讀卡器上電開機上傳設備信息 break; case 0xf6: Analyze_f6(ip, port,databuff,buflen); //在線設備響應查詢型號、固件日期指令的返回 break; case 0xa4: Analyze_a4(ip, port,databuff,buflen); //查詢WIFI叁數的返回 break; case 0x4b: Analyze_4b(ip, port,databuff,buflen); //設置主動讀M1卡扇區號及認證密鑰的返回 break; default: break; } } //設置主動讀M1卡扇區號及認證密鑰的返回--------------------------------------------------------------------------------------------------- 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]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 ui-?>label_msg_2->setText("設備IP:"+IPAddress+",機號:"+DeviceNumber+",設置讀卡扇區及認證密鑰成功!"); ui->textEdit_msg->setText("設備IP:"+IPAddress+",機號:"+DeviceNumber+",設置讀卡扇區及認證密鑰成功!"); if(ui->checkBox_Resp->isChecked()){Respondinfo("設置讀卡扇區及認證密鑰成功!",ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 } //確認接收到的信息---------------------------------------------------------------------------------------------------------------- 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+" 確定接收,不要再次發送此幀數據啦..."); } //解析讀取IC卡卡號------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_c1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { DisableSendAgain(ip, port,databuff,buflen);//確認接收到的信息,否則同一信息讀卡器會重發三次 QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //數據包號 QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X", databuff[10],databuff[11],databuff[12],databuff[13]); //16進制卡號正碼 QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[13],databuff[12],databuff[11],databuff[10]); //16進制卡號反碼 bool status; QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //轉8H10D反碼卡號 QString SerialNumber=""; //設備全球唯一硬件序號 for (int i=14;itextEdit_M1UID->setText(CardnoHexZ); if(ui->checkBox_Resp->isChecked()){Respondinfo(MyClass::getsysdatetime()+"卡號:"+Cardno8H10D,ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 } //主動讀取扇區數據的返回-------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_c3(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 QString CardnoHex=""; for (int i=12;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卡扇區數據成功,設備IP:"+IPAddress+",機號:"+DeviceNumber+",16進制卡號:"+CardnoHex; listadditems(1,DispInf); ui->textEdit_M1UID->setText(CardnoHex); if(ui->checkBox_Resp->isChecked()){Respondinfo(MyClass::getsysdatetime()+"卡號:"+CardnoHex,ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 } } //主動寫M1卡扇區數據指令的返回-------------------------------------------------------------------------------------------------------------- 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]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 if(databuff[7]+databuff[8]>=writcardlen){ //全部寫卡數據已經發送完畢 ui->textEdit_msg->setPlainText("設備IP:"+IPAddress+",機號:"+DeviceNumber+",寫卡成功!"); if(ui->checkBox_Resp->isChecked()){Respondinfo("寫扇區數據成功!",ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 }else{ QByteArray RespBuff; //寫卡數據超過4個扇區,需要繼續發送 RespBuff.append(0x3c); //功能碼 quint16 devno=0; RespBuff.append(devno % 256); //機號低位 RespBuff.append(devno / 256); //機號高位,高低位都為0表示所有機 RespBuff.append(writcarepoi); //當前已寫扇區指針 int j=writcardlen - writcarepoi; if(j>4){j=4;}; RespBuff.append(j); //本次總計寫扇區數,一次最多寫4扇區,多于4扇區要分次寫入 for (int i=0;i4;i++){ //加入4個字節的卡號,卡號為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; } } //指定區號密鑰讀取M1扇區數據返回----------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_c5(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 QString CardnoHex=""; QString DispInf=""; for (int i=8;i12;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); } QString Sector=QString::asprintf("%d", databuff[12]); //扇區號 DispInf="讀取M1卡"+Sector+"扇區數據"; switch (databuff[13]){ case 0: { QString DataHex=""; for (int i=0;i48;i++){ DataHex=DataHex+QString::asprintf("%02X ", databuff[14+i]); } DispInf=DispInf+"成功,設備IP:"+IPAddress+",機號:"+DeviceNumber+",16進制卡號:"+CardnoHex; ui-?>textEdit_data->setPlainText(DataHex); break; } case 8: DispInf=DispInf+"失敗,設備IP:"+IPAddress+",機號:"+DeviceNumber+",沒有卡片在感應區!"; break; case 12: DispInf=DispInf+"失敗,設備IP:"+IPAddress+",機號:"+DeviceNumber+",16進制卡號:"+CardnoHex+",卡密碼認證失敗!"; break; default: DispInf=DispInf+"失敗,設備IP:"+IPAddress+",機號:"+DeviceNumber+",錯誤代碼:"+QString::asprintf("%d", databuff[13]); break; } listadditems(1,DispInf); ui->textEdit_M1UID->setText(CardnoHex); if(ui->checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 } //指定區號密鑰寫數據到M1卡扇區返回狀態--------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_cd(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4])+"."+QString::asprintf("%d", databuff[5]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[6]+databuff[7]*256); //設備自編機號 QString CardnoHex=""; for (int i=9;i13;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); //16進制卡號 } QString Sector=QString::asprintf("%d", databuff[13]); //扇區號 QString Pages=QString::asprintf("%d", databuff[8]); //本次操作的扇區總數 QString DispInf=""; if(databuff[1]==0x3a){ DispInf="修改M1卡"+Sector+"扇區密鑰"; }else if(databuff[1]==0x3d){ DispInf="寫數據到M1卡"+Sector+"扇區"; } switch (databuff[14]){ case 0: DispInf=DispInf+"成功,設備IP:"+IPAddress+",機號:"+DeviceNumber+",16進制卡號:"+CardnoHex; break; case 8: DispInf=DispInf+"失敗,設備IP:"+IPAddress+",機號:"+DeviceNumber+",沒有卡片在感應區!"; break; case 12: DispInf=DispInf+"失敗,設備IP:"+IPAddress+",機號:"+DeviceNumber+",16進制卡號:"+CardnoHex+",卡密碼認證失敗!"; break; default: DispInf=DispInf+"失敗,設備IP:"+IPAddress+",機號:"+DeviceNumber+",錯誤代碼:"+QString::asprintf("%d", databuff[13]); break; } listadditems(1,DispInf); if(ui-?>checkBox_Resp->isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 } //解析讀取ID卡卡號----------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_d1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { DisableSendAgain(ip, port,databuff,buflen);//確認接收到的信息,否則同一信息讀卡器會重發三次 QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //數據包號 QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X%02X", databuff[9],databuff[10],databuff[11],databuff[12],databuff[13]); //16進制卡號正碼,databuff[13]為廠商代碼 QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[12],databuff[11],databuff[10],databuff[9]); //16進制卡號反碼,databuff[13]為廠商代碼 bool status; QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //轉8H10D反碼卡號 QString SerialNumber=""; //設備全球唯一硬件序號 for (int i=14;icheckBox_Resp->isChecked()){Respondinfo(MyClass::getsysdatetime()+"卡號:"+Cardno8H10D,ip,port,DeviceNumber);} //回應驅動設備顯示+蜂鳴響聲 } //解析ICID卡離開讀卡器----------------------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_cf_df(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { DisableSendAgain(ip, port,databuff,buflen);//確認接收到的信息,否則同一信息讀卡器會重發三次 QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //數據包號 int infotype=databuff[9]; //數據說明,1表示只讀取UID卡號 int cardnolen=databuff[10]; //UID卡號長度 QString CardnoHexZ=""; //16進制卡號正碼 for (int i=0;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); //自動列寬 } } //響應查詢設備型號固件日期指令的返回--------------------------------------------------------------------------------------------------- void MainWindow::Analyze_f6(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //設備IP QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //設備自編機號 int NameLen=databuff[7]; //設備型號名稱長度 QByteArray namebuf; //設備型號 for (int i=0;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連接狀態--------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_a4(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[7])+"."+QString::asprintf("%d", databuff[8])+"."+QString::asprintf("%d", databuff[9])+"."+QString::asprintf("%d", databuff[10]); //設備IP地址,廣域網上使用,一般不對此IP回應,而是對數據流的 ip及端口 回應 ui->listWidget_wifi->addItem("WIFI的IP地址:"+IPAddress); QString mask=QString::asprintf("%d", databuff[11])+"."+QString::asprintf("%d", databuff[12])+"."+QString::asprintf("%d", databuff[13])+"."+QString::asprintf("%d", databuff[14]); //設備掩碼 ui->listWidget_wifi->addItem("WIFI子網掩碼:"+mask); QString MACStr=QString::asprintf("%02X", databuff[15])+"-"+QString::asprintf("%02X", databuff[16])+"-"+QString::asprintf("%02X", databuff[17])+"-"+QString::asprintf("%02X", databuff[18])+"-"+QString::asprintf("%02X", databuff[19])+"-"+QString::asprintf("%02X", databuff[20]); //MAC地址 ui->listWidget_wifi->addItem("WIFI_MAC地址:"+MACStr); QString GateWay=QString::asprintf("%d", databuff[21])+"."+QString::asprintf("%d", databuff[22])+"."+QString::asprintf("%d", databuff[23])+"."+QString::asprintf("%d", databuff[24]); //設備網關 ui->listWidget_wifi->addItem("WIFI網關地址:"+GateWay); QString GatewayMAC=QString::asprintf("%02X", databuff[25])+"-"+QString::asprintf("%02X", databuff[26])+"-"+QString::asprintf("%02X", databuff[27])+"-"+QString::asprintf("%02X", databuff[28])+"-"+QString::asprintf("%02X", databuff[29])+"-"+QString::asprintf("%02X", databuff[30]); //網關MAC ui->listWidget_wifi->addItem("網關 MAC地址:"+GatewayMAC); switch (databuff[31]){ case 0: ui->listWidget_wifi->addItem("WIFI網絡狀態:已連接wifi"); break; case 1: ui->listWidget_wifi->addItem("WIFI網絡狀態:連接失敗!"); break; case 2: ui->listWidget_wifi->addItem("WIFI網絡狀態:已初始化!"); break; default: ui->listWidget_wifi->addItem("WIFI網絡狀態:未初始化!"); break; } QByteArray devname; for(int i=0 ;ilistWidget_wifi->addItem("讀卡器 名稱:"+devnamestr); QByteArray wifname; for(int i=0 ;ilistWidget_wifi->addItem("WIFI熱點名稱:"+wifinamestr); } //更換不同的網卡---------------------------------------------------------------------------------------------------- void MainWindow::on_CBIP_currentIndexChanged(int index) { if (listening){ disconnect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data); udpSocket->close(); listening=false; listadditems(0,MyClass::getsystime()+" Sock偵聽已關閉!"); } sockinit(); } void MainWindow::on_PBClear_clicked() { ui->listWidget->clear(); ui->textEdit_msg->setText(""); } //在在線設備列表中選取一臺設備IP端口 void MainWindow::on_tableWidget_cellClicked(int row, int column) { int currentRow = ui->tableWidget->currentIndex().row(); QString DeviceNumber = ui->tableWidget->item(currentRow,0)->text(); QString IPAddress= ui->tableWidget->item(currentRow,1)->text(); QString PortStr= ui->tableWidget->item(currentRow,3)->text(); ui->textEdit_DeviceNumber->setText(DeviceNumber); ui->textEdit_remoiport->setText(IPAddress+":"+PortStr); ui->New_Nember->setText(DeviceNumber); ui->New_IP->setText(IPAddress); ui->New_ServerIP->setText( ui->tableWidget->item(currentRow,6)->text()); ui->ServerMAC->setText( ui->tableWidget->item(currentRow,7)->text()); ui->New_Mask->setText( ui->tableWidget->item(currentRow,2)->text()); ui->New_Gateway->setText( ui->tableWidget->item(currentRow,4)->text()); ui->GateWayMac->setText( ui->tableWidget->item(currentRow,5)->text()); ui->New_Port->setText( ui->tableWidget->item(currentRow,3)->text()); ui->Serial_Number->setText( ui->tableWidget->item(currentRow,10)->text()); quint8 functionid=ui->tableWidget->item(currentRow,9)->text().toInt(); if((functionid % 2)>0){ui->checkBox_beep->setChecked(true);}else{ui->checkBox_beep->setChecked(false);} functionid=functionid/2; if((functionid % 2)>0){ui->checkBox_dhcp->setChecked(true);}else{ui->checkBox_dhcp->setChecked(false);} functionid=functionid/2; ui->comboBox_out->setCurrentIndex(functionid % 2); functionid=functionid/2; functionid=functionid % 8; if (functionid<=4){ui-?>comboBox_in->setCurrentIndex(functionid);}else{ui->comboBox_in->setCurrentIndex(0);} quint8 automac=ui->tableWidget->item(currentRow,8)->text().toInt(); switch (automac){ case 0: ui->radioButton1->setChecked(false); ui->radioButton2->setChecked(true); ui->radioButton3->setChecked(false); ui->radioButton4->setChecked(true); break; case 1: ui->radioButton1->setChecked(true); ui->radioButton2->setChecked(false); ui->radioButton3->setChecked(false); ui->radioButton4->setChecked(true); break; case 2: ui->radioButton1->setChecked(false); ui->radioButton2->setChecked(true); ui->radioButton3->setChecked(true); ui->radioButton4->setChecked(false); break; default: ui->radioButton1->setChecked(true); ui->radioButton2->setChecked(false); ui->radioButton3->setChecked(true); ui->radioButton4->setChecked(false); break; } } void MainWindow::on_PBEditpara_clicked() { int currentRow = ui->tableWidget->currentIndex().row(); if (currentRow0){ QMessageBox::critical(this, "警告", "請選擇一臺在線設備再執行此功能!", QMessageBox::Ok); }else{ ui-?>scrollArea_wifi->setVisible(false); ui->scrollArea->setVisible(true); ui->scrollArea_config->setVisible(false); } } //將sendData緩沖數據發送到指定的設備IP端口--------------------------------------------------------------------------------------- void MainWindow:: SendBuffAct() { QString RemoIPort=ui->textEdit_remoiport->toPlainText(); QStringList liststr = RemoIPort.split(":"); QHostAddress Remoip(liststr[0]); quint16 Remoport=liststr[1].toUInt(); udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress(Remoip), Remoport); QString SendHex=MyClass::getsystime()+" Send To: "+(Remoip.toString()+":"+QString::asprintf("%d",Remoport)+" ").mid(0,22); SendHex=SendHex+MyClass::ByteArrayToHexString(sendData); listadditems(0,SendHex); } //驅動設備蜂鳴響聲+文字顯示------------------------------------------------------------------------------------------------- void MainWindow::on_PBSendDispBeep_clicked() { sendData.clear(); sendData.append(0x5A); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(ui->CBbeep->currentIndex()); //蜂鳴響聲代碼,255表示不響聲 sendData.append(ui->spinBox_dispdelay->value()); //文字顯示時長, QString dispstr=ui->textEdit_disp->toPlainText()+" "; //加空格是為了確保滿屏34位顯示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;i34;i++){ sendData.append(Dispbyte[i]); } SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } //驅動設備蜂鳴響聲----------------------------------------------------------------------------------------------------------- void MainWindow::on_PBbeep_clicked() { sendData.clear(); sendData.append(0x96); //功能碼 quint16 devno=ui-?>textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(ui->CBbeep->currentIndex()); //蜂鳴響聲代碼 SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } //驅動設備開啟繼電器---------------------------------------------------------------------------------------------------------- void MainWindow::on_PBSwitchOn_clicked() { sendData.clear(); sendData.append(0x78); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //選擇繼電器 quint16 deltime=ui->spinBox_swit->value(); sendData.append(deltime % 256); //開啟延時低位 sendData.append(deltime / 256); //開啟延時高位 SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } //驅動設備關閉繼電器---------------------------------------------------------------------------------------------------------- void MainWindow::on_PBSwitchOff_clicked() { sendData.clear(); sendData.append(0x78); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 QString swithno="E"+QString::asprintf("%d",ui->CBSwitch->currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //選擇繼電器 quint16 deltime=ui->spinBox_swit->value(); sendData.append(deltime % 256); //延時低位 sendData.append(deltime / 256); //延時高位 SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } //驅動設備顯示文字+蜂鳴響聲+播報TTS語音+開啟繼電器開關------------------------------------------------------------------------------ void MainWindow::on_PBSendDispTTS_clicked() { if(ui->spinBox_voice->value()>16){ui->spinBox_voice->setValue(16);} //tts最大語音取值16 QString strls="[v"+QString::asprintf("%d",ui->spinBox_voice->value())+"]"; strls=strls+ui->textEdit_tts->toPlainText().trimmed(); QByteArray SpeakArr=strls.toLocal8Bit(); //TS語音轉換為Ansi碼 quint8 speakbytes=SpeakArr.size(); quint8 dispbytes=34; //雙行顯示屏顯示長度34,四行屏顯示長度72 sendData.clear(); sendData.append(0x5c); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(ui->CBbeep->currentIndex()); //蜂鳴響聲代碼,取值255表示不響 QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //選擇繼電器 quint16 deltime=ui->spinBox_swit->value(); sendData.append(deltime % 256); //延時低位 sendData.append(deltime / 256); //延時高位 sendData.append(ui->spinBox_dispdelay->value()); //文字顯示時長, quint8 begindisp =0; //在顯示屏中的哪個位置開始顯示,一般取0 sendData.append(begindisp); sendData.append(dispbytes); //顯示文字長度 sendData.append(speakbytes); //tts語音長茺 QString dispstr=ui->textEdit_disp->toPlainText()+" "; //加空格是為了確保滿屏34位顯示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;itextEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(ui->CBbeep->currentIndex()); //蜂鳴響聲代碼,取值255表示不響 QString swithno="F"+QString::asprintf("%d",ui->CBSwitch->currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //選擇繼電器 quint16 deltime=ui->spinBox_swit->value(); sendData.append(deltime % 256); //延時低位 sendData.append(deltime / 256); //延時高位 sendData.append(ui->spinBox_dispdelay->value()); //文字顯示時長, sendData.append(begindisp); //顯示起始位置 sendData.append(dispbytes); //顯示字符串長度 sendData.append(lensy); //語音代碼條數 QString dispstr=ui->textEdit_disp->toPlainText()+" "; //加空格是為了確保滿屏34位顯示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;itextEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感應區內任意卡,如要操作特定卡可指定卡號 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen4){ QMessageBox::critical(NULL, "提示", "請輸入8位正確的16進制卡號!"); ui-?>textEdit_M1UID->setFocus(); return; } QString keyinf = ui->textEdit_authkey->toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進制卡密碼!"); ui-?>textEdit_authkey->setFocus(); return; } sendData.clear(); sendData.append(0x3b); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(0x01); //本次操作的區數 for (int i=0 ;i4;i++){ //指定讀寫的卡號,全為0 表示可讀寫任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui-?>CBPage->currentIndex()); //本次操作的扇區號 sendData.append(ui->CBauth->currentIndex()); //為1以B密碼來驗證舊密碼,為0以A密碼來驗證舊密碼 for (int i=0 ;i6;i++){ sendData.append(keybuf[i]); //認證密鑰 } SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } //指定扇區密鑰寫入數據到M1卡扇區---------------------------------------------------------------------------------------- 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"表示可能操作感應區內任意卡,如要操作特定卡可指定卡號 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen4){ QMessageBox::critical(NULL, "提示", "請輸入8位正確的16進制卡號!"); ui-?>textEdit_M1UID->setFocus(); return; } QString keyinf = ui->textEdit_authkey->toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進制卡密碼!"); 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, "警告", "有效的寫卡數據不足一扇區48字節,是否要補0寫入到指定扇區?", 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, "警告", "本指令只可以寫一個扇區數據,是否將前48個數據寫入到指定扇區?", QMessageBox::Ok, QMessageBox::Cancel); if (answ !=1024){ ui->textEdit_data->setFocus(); return; } } } sendData.clear(); sendData.append(0x3d); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(0x01); //本次操作的區數 for (int i=0 ;i4;i++){ //指定讀寫的卡號,全為0 表示可讀寫任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui-?>CBPage->currentIndex()); //本次操作的扇區號 sendData.append(ui->CBauth->currentIndex()); //為1以B密碼來驗證舊密碼,為0以A密碼來驗證舊密碼 for (int i=0 ;i6;i++){ sendData.append(keybuf[i]); //認證密鑰 } for (int i=0 ;i48;i++){ sendData.append(writecardbuf[i]); //寫卡數據 } sendData.append(0x55); //防干擾后綴 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } //修改M1卡扇區密鑰------------------------------------------------------------------------------------------------- void MainWindow::on_PBChangeKey_clicked() { int answ=QMessageBox::question (this, "警告", "執行此操作前請記住卡片新密鑰,否則卡片將報廢!是否繼續?", QMessageBox::Ok, QMessageBox::Cancel); if (answ !=1024){ ui-?>textEdit_data->setFocus(); return; } unsigned char cardnobuf[4]; //卡號 unsigned char keybuf[6]; //密鑰 unsigned char newkeybuf[20]; //新密鑰 int keylen; int cardnolen; int newkeylen; QString cardnostr ="00000000"; // ui->textEdit_M1UID->toPlainText().trimmed(); "00000000"表示可能操作感應區內任意卡,如要操作特定卡可指定卡號 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen4){ QMessageBox::critical(NULL, "提示", "請輸入8位正確的16進制卡號!"); ui-?>textEdit_M1UID->setFocus(); return; } QString keyinf = ui->textEdit_authkey->toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen6){ QMessageBox::critical(NULL, "提示", "請輸入12位正確的16進制卡密碼!"); ui-?>textEdit_authkey->setFocus(); return; } QString newkey = ui->textEdit_newkey->toPlainText().trimmed(); newkeylen=MyClass::checkhexdata(newkey,newkeybuf); if(newkeylen16){ QMessageBox::critical(NULL, "提示", "請輸16進制 6字節A密碼+4字節控制位+6字節B密碼 !"); ui-?>textEdit_newkey->setFocus(); return; } sendData.clear(); sendData.append(0x3a); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(0x01); //本次操作的區數 for (int i=0 ;i4;i++){ //指定讀寫的卡號,全為0 表示可讀寫任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui-?>CBPage->currentIndex()); //本次操作的扇區號 quint8 auth=ui->CBauth->currentIndex(); //為1以B密碼來驗證舊密碼,為0以A密碼來驗證舊密碼 auth=auth+ui->ChangeKey->currentIndex()*2; //修改A、B、控制位 sendData.append(auth); for (int i=0 ;i6;i++){ sendData.append(keybuf[i]); //認證密鑰 } 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緩沖數據發送到指定的設備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, "提示", "顯示數據報文已拷貝到剪切板"); } } //接收到刷卡數據立即回應-------------------------------------------------------------------------- void MainWindow::Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber) { QByteArray RespBuff; RespBuff.append(0x5A); //功能碼 quint16 devno=DeviceNumber.toUInt(); RespBuff.append(devno % 256); //機號低位 RespBuff.append(devno / 256); //機號高位,高低位都為0表示所有機 RespBuff.append(ui->CBbeep->currentIndex()); //蜂鳴響聲代碼,255表示不響聲 RespBuff.append(ui->spinBox_dispdelay->value()); //文字顯示時長, QString dispstr=Dispinf+" "; //加空格是為了確保滿屏34位顯示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;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, "提示", "請輸入有效的設備IP!"); ui->New_IP->setFocus(); return; } QString newmask=ui->New_Mask->text().trimmed(); if (!MyClass::isValidIP(newmask)){ QMessageBox::critical(NULL, "提示", "請輸入有效的設備掩碼!"); ui->New_Mask->setFocus(); return; } QString newserverip=ui->New_ServerIP->text().trimmed(); if (!MyClass::isValidIP(newserverip)){ QMessageBox::critical(NULL, "提示", "請輸入有效的遠程服務器ip!"); ui->New_ServerIP->setFocus(); return; } QString newgateway=ui->New_Gateway->text().trimmed(); if (!MyClass::isValidIP(newgateway)){ QMessageBox::critical(NULL, "提示", "請輸入有效的網關!"); ui->New_Gateway->setFocus(); return; } QString servermac=ui->ServerMAC->text().trimmed(); if (!MyClass::isValidMac(servermac)){ QMessageBox::critical(NULL, "提示", "請輸入有效的遠程服務器MAC!"); ui->ServerMAC->setFocus(); return; } QString gatemac=ui->GateWayMac->text().trimmed(); if (!MyClass::isValidMac(gatemac)){ QMessageBox::critical(NULL, "提示", "請輸入有效的網關MAC!"); ui->GateWayMac->setFocus(); return; } bool ok; sendData.clear(); sendData.append(0xf9); //功能碼 QStringList liststr = newip.split("."); //新IP for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = newmask.split("."); //掩碼 for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = newserverip.split("."); //遠程服務器IP for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = servermac.split("-"); //遠程服務器MAC for (int i=0 ;i6;i++){ sendData.append(liststr[i].toInt(&ok,16)); } liststr = newgateway.split("."); //網關 for (int i=0 ;i4;i++){ sendData.append(liststr[i].toInt()); } liststr = gatemac.split("-"); //網關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); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 quint16 newport=ui->New_Port->text().toInt(); sendData.append(newport % 256); //端口低位 sendData.append(newport / 256); //端口高位 QString seri=ui->Serial_Number->text().trimmed(); liststr = seri.split("-"); //模塊序號 for (int i=0 ;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()){ //使用廣播方式發送指令 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緩沖數據發送到指定的設備IP端口 } } void MainWindow::on_pushButton_SetTCP_clicked() { sendData.clear(); sendData.append(0x1d); //功能碼 quint16 devno=0; //機號,0表示所有機 sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(7); //指令長度 sendData.append(0x5c); //修改TCP通訊端口功能碼 sendData.append(4); //數據長度 quint16 devport=ui->New_Port->text().toUInt(); //讀卡器端口 sendData.append(devport % 256); //低位 sendData.append(devport / 256); //高位 quint16 serverport=ui->lineEdit_TCPRemoPort->text().toUInt(); //遠程TCP服務器端口 sendData.append(serverport % 256); //低位 sendData.append(serverport / 256); //高位 quint8 crc=sendData[6]^sendData[7]^sendData[8]^sendData[9]; //數據校驗位 sendData.append(crc); sendData.append(0x55); //防干擾后綴 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); if (ui->checkBox_broadcast->isChecked()){ //使用廣播方式發送指令 QHostAddress broadcastAddress("255.255.255.255"); quint16 port1 = 39169; udpSocket->writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1); QString dispinf=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緩沖數據發送到指定的設備IP端口 } } void MainWindow::on_pushButton_SetHttp_clicked() { QString filenamestr=ui->lineEdit_filename->text().trimmed(); QByteArray filebyte=filenamestr.toLocal8Bit(); if(filebyte.size()1){ QMessageBox::critical(NULL, "提示", "請輸入正確的訪問文件,可以是.asp\.jsp\.php等腳本文件!"); ui-?>lineEdit_filename->setFocus(); return; } sendData.clear(); sendData.append(0x1d); //功能碼 quint16 devno=0; //機號,0表示所有機 sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(filebyte.size()+7); //指令長度 sendData.append(0x5b); //設置http協議讀卡器訪問文件、端口、提效方式的識別碼 sendData.append(filebyte.size()+4); //數據長度 sendData.append(ui->comboBox_Sendmodel->currentIndex()); //提交方式 sendData.append(0xff); quint16 serverport=ui->lineEdit_HttpRemoPort->text().toUInt(); //遠程http服務器端口 sendData.append(serverport % 256); //低位 sendData.append(serverport / 256); //高位 quint8 crc= sendData[6]^ sendData[7]^ sendData[8]^sendData[9]; for(int i=0;icheckBox_broadcast->isChecked()){ //使用廣播方式發送指令 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緩沖數據發送到指定的設備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, "警告", "請選擇一臺在線設備再執行此功能!", 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熱點名稱長度不可大于60,不可為空!"); ui->lineEdit_SSID->setFocus(); return; } QString wifipass=ui->lineEdit_Password->text().trimmed(); QByteArray wifipassarry=wifipass.toUtf8(); //注意編碼格式 if(wifipassarry.size()>64){ QMessageBox::critical(NULL, "提示", "WIFI密碼長度不可以大于64!"); ui->lineEdit_Password->setFocus(); return; } sendData.clear(); sendData.append(0xf7); //功能碼 quint16 devno=0; //機號,0表示所有機 sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(wifiNamearry.size()); //熱點名稱長度 quint8 passlen=0; if(ui->checkBox_wifikey->isChecked()){ passlen=wifipassarry.size(); } sendData.append(passlen); //密碼長度 int i=0; for (i=0;iradioButton_IP->isChecked()){ sendData.append(1); QString ipstr=ui->lineEdit_IP->text().trimmed(); if (!MyClass::isValidIP(ipstr)){ QMessageBox::critical(NULL, "提示", "請輸入有效的設備IP!"); ui->lineEdit_IP->setFocus(); return; } QString mskstr=ui->lineEdit_mask->text().trimmed(); if (!MyClass::isValidIP(mskstr)){ QMessageBox::critical(NULL, "提示", "請輸入正確的讀卡器子網掩碼!"); ui->lineEdit_mask->setFocus(); return; } QString gatewaystr=ui->lineEdit_gateway->text().trimmed(); if (!MyClass::isValidIP(gatewaystr)){ QMessageBox::critical(NULL, "提示", "請輸入正確的讀卡器網關!"); 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("."); //網關 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緩沖數據發送到指定的設備IP端口 } void MainWindow::on_pushButton_Read_clicked() { ui->listWidget_wifi->clear(); sendData.clear(); sendData.append(0xa4); //功能碼 quint16 devno=ui->textEdit_DeviceNumber->toPlainText().toUInt(); sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 SendBuffAct(); //將sendData緩沖數據發送到指定的設備IP端口 } 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字節機號都取0表示任意機 sendbuff[2]=0x00; sendbuff[3]=0x00; //主動讀卡的扇區數量 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進制卡密碼!"); myTextEdit-?>setFocus(); return; } sendbuff[3]=sendbuff[3]+1; //主動讀卡的扇區數量加1 sendbuff[j]=i; //扇區號 if(myComboBox->currentIndex()>0){ sendbuff[j]=sendbuff[j] | 128; //密鑰認證方式 } for(int p=0;p6;p++){ //認證密鑰 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緩沖數據發送到指定的設備IP端口 ui-?>label_msg_2->setText("設置主動讀卡扇區及認證密鑰的指令已發送..."); } void MainWindow::on_PBwritecard_clicked() { int currentRow = ui->tableWidget->currentIndex().row(); if (currentRow0){ QMessageBox::critical(this, "警告", "請選擇一臺在線設備再執行此功能!", 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, "警告", "寫卡數據輸入錯誤,入寫卡字節數必須為 48 的倍數的16進制數據!", QMessageBox::Ok); return; } writcardlen=j/48; writcarepoi=0; if(writcardlen?>0){ sendData.clear(); sendData.append(0x3c); //功能碼 quint16 devno=0; sendData.append(devno % 256); //機號低位 sendData.append(devno / 256); //機號高位,高低位都為0表示所有機 sendData.append(writcarepoi); //當前已寫扇區指針 j=writcardlen - writcarepoi; if(j>4){j=4;}; sendData.append(j); //本次總計寫扇區數,一次最多寫4扇區,多于4扇區要分次寫入 for (int i=0;i4;i++){ //加入4個字節的卡號,卡號為0表示可以操作任意卡 sendData.append(1-1); } for (int i=0;i
-
IC卡
+關注
關注
2文章
168瀏覽量
34131 -
TCP
+關注
關注
8文章
1362瀏覽量
79108 -
Qt
+關注
關注
1文章
307瀏覽量
37942
發布評論請先 登錄
相關推薦
評論