电子说
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;i< 9;i++){ sendData.append(databuff[i]); SendHex=SendHex+QString::asprintf("%02X ", databuff[i]); } udpSocket- >writeDatagram(sendData.constData(), sendData.size(), QHostAddress(ip), port); listadditems(0,SendHex+" 确定接收,不要再次发送此帧数据啦..."); } //解析读取IC卡卡号------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_c1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次 QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号 QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //数据包号 QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X", databuff[10],databuff[11],databuff[12],databuff[13]); //16进制卡号正码 QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[13],databuff[12],databuff[11],databuff[10]); //16进制卡号反码 bool status; QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //转8H10D反码卡号 QString SerialNumber=""; //设备全球唯一硬件序号 for (int i=14;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;i< 16;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); } int j=databuff[10]*48; int m=databuff[11]*48; for(int i=0;i< m;i++){ readcardbuf[j+i]=databuff[16+i]; } if((databuff[10]+databuff[11]) >=databuff[9]){ m=databuff[9]*48; QString DataHex=""; for (int i=0;i< m;i++){ DataHex=DataHex+QString::asprintf("%02X ",readcardbuf[i]); } ui- >textEdit_data- >setPlainText(DataHex); QString DispInf="读取M1卡扇区数据成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex; listadditems(1,DispInf); ui- >textEdit_M1UID- >setText(CardnoHex); if(ui- >checkBox_Resp- >isChecked()){Respondinfo(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;i< 4;i++){ //加入4个字节的卡号,卡号为0表示可以操作任意卡 RespBuff.append(1-1); } for (int i=0;i< j*48;i++){ RespBuff.append(writecardbuf[writcarepoi*48+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); 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;i< 12;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); } QString Sector=QString::asprintf("%d", databuff[12]); //扇区号 DispInf="读取M1卡"+Sector+"扇区数据"; switch (databuff[13]){ case 0: { QString DataHex=""; for (int i=0;i< 48;i++){ DataHex=DataHex+QString::asprintf("%02X ", databuff[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;i< 13;i++){ CardnoHex=CardnoHex+QString::asprintf("%02X", databuff[i]); //16进制卡号 } QString Sector=QString::asprintf("%d", databuff[13]); //扇区号 QString Pages=QString::asprintf("%d", databuff[8]); //本次操作的扇区总数 QString DispInf=""; if(databuff[1]==0x3a){ DispInf="修改M1卡"+Sector+"扇区密钥"; }else if(databuff[1]==0x3d){ DispInf="写数据到M1卡"+Sector+"扇区"; } switch (databuff[14]){ case 0: DispInf=DispInf+"成功,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex; break; case 8: DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",没有卡片在感应区!"; break; case 12: DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",16进制卡号:"+CardnoHex+",卡密码认证失败!"; break; default: DispInf=DispInf+"失败,设备IP:"+IPAddress+",机号:"+DeviceNumber+",错误代码:"+QString::asprintf("%d", databuff[13]); break; } listadditems(1,DispInf); if(ui- >checkBox_Resp- >isChecked()){Respondinfo(DispInf,ip,port,DeviceNumber);} //回应驱动设备显示+蜂鸣响声 } //解析读取ID卡卡号----------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_d1(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { DisableSendAgain(ip, port,databuff,buflen);//确认接收到的信息,否则同一信息读卡器会重发三次 QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应 QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号 QString FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256); //数据包号 QString CardnoHexZ=QString::asprintf("%02X%02X%02X%02X%02X", databuff[9],databuff[10],databuff[11],databuff[12],databuff[13]); //16进制卡号正码,databuff[13]为厂商代码 QString CardnoHexF=QString::asprintf("%02X%02X%02X%02X", databuff[12],databuff[11],databuff[10],databuff[9]); //16进制卡号反码,databuff[13]为厂商代码 bool status; QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //转8H10D反码卡号 QString SerialNumber=""; //设备全球唯一硬件序号 for (int i=14;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;i< cardnolen;i++){ CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[11+i]); } QString CardnoHexF=CardnoHexZ.mid(6,2)+CardnoHexZ.mid(4,2)+CardnoHexZ.mid(2,2)+CardnoHexZ.mid(0,2); //16进制卡号反码 bool status; QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16)); //转8H10D反码卡号 QString SerialNumber=""; //设备全球唯一硬件序号 for (int i=11+cardnolen;itableWidget- >insertRow(row); QTableWidgetItem* item = new QTableWidgetItem; item- >setText(DeviceNumber); ui- >tableWidget- >setItem(row,0, item); item = new QTableWidgetItem; item- >setText(IPAddress); ui- >tableWidget- >setItem(row,1, item); item = new QTableWidgetItem; item- >setText(mask); ui- >tableWidget- >setItem(row,2, item); item = new QTableWidgetItem; item- >setText(PortStr); ui- >tableWidget- >setItem(row,3, item); item = new QTableWidgetItem; item- >setText(GetWay); ui- >tableWidget- >setItem(row,4, item); item = new QTableWidgetItem; item- >setText(GetWayMAC); ui- >tableWidget- >setItem(row,5, item); item = new QTableWidgetItem; item- >setText(ServerIp); ui- >tableWidget- >setItem(row,6, item); item = new QTableWidgetItem; item- >setText(ServerMAC); ui- >tableWidget- >setItem(row,7, item); item = new QTableWidgetItem; item- >setText(MACPara); ui- >tableWidget- >setItem(row,8, item); item = new QTableWidgetItem; item- >setText(NetPara); ui- >tableWidget- >setItem(row,9, item); item = new QTableWidgetItem; item- >setText(ModuleNumber); ui- >tableWidget- >setItem(row,10, item); item = new QTableWidgetItem; item- >setText(STMAC); ui- >tableWidget- >setItem(row,11, item); item = new QTableWidgetItem; item- >setText(SerialNumber); ui- >tableWidget- >setItem(row,12, item); item = new QTableWidgetItem; item- >setText(CHMAC); ui- >tableWidget- >setItem(row,13, item); for (int i=0;i<=13;i++){ ui- >tableWidget- >resizeColumnToContents(i); //自动列宽 } } //响应查询设备型号固件日期指令的返回--------------------------------------------------------------------------------------------------- void MainWindow::Analyze_f6(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[1])+"."+QString::asprintf("%d", databuff[2])+"."+QString::asprintf("%d", databuff[3])+"."+QString::asprintf("%d", databuff[4]); //设备IP QString DeviceNumber=QString::asprintf("%05d",databuff[5]+databuff[6]*256); //设备自编机号 int NameLen=databuff[7]; //设备型号名称长度 QByteArray namebuf; //设备型号 for (int i=0;i< NameLen;i++){ namebuf.append(databuff[8+i]); } QString namestr=namebuf; int VersionDateLen=databuff[8 + NameLen]; //固件日期长度 QByteArray verbuf; //固件日期 for (int i=0;i< VersionDateLen;i++){ verbuf.append(databuff[8 + NameLen + 1+i]); } QString verdatestr=verbuf; int rowCount = ui- >tableWidget- >rowCount(); for (int row = 0; row < rowCount; ++row) { QTableWidgetItem *item = ui- >tableWidget- >item(row, 1); QString ipstr = item- >text(); if (IPAddress==ipstr){ item = new QTableWidgetItem; item- >setText(namestr); ui- >tableWidget- >setItem(row,14, item); ui- >tableWidget- >resizeColumnToContents(14); //自动列宽 item = new QTableWidgetItem; item- >setText(verdatestr); ui- >tableWidget- >setItem(row,15, item); ui- >tableWidget- >resizeColumnToContents(15); //自动列宽 return; } } } //查询wifi连接状态--------------------------------------------------------------------------------------------------------------------- void MainWindow::Analyze_a4(QHostAddress ip,quint16 port,unsigned char databuff[], qint64 buflen) { QString IPAddress=QString::asprintf("%d", databuff[7])+"."+QString::asprintf("%d", databuff[8])+"."+QString::asprintf("%d", databuff[9])+"."+QString::asprintf("%d", databuff[10]); //设备IP地址,广域网上使用,一般不对此IP回应,而是对数据流的 ip及端口 回应 ui- >listWidget_wifi- >addItem("WIFI的IP地址:"+IPAddress); QString mask=QString::asprintf("%d", databuff[11])+"."+QString::asprintf("%d", databuff[12])+"."+QString::asprintf("%d", databuff[13])+"."+QString::asprintf("%d", databuff[14]); //设备掩码 ui- >listWidget_wifi- >addItem("WIFI子网掩码:"+mask); QString MACStr=QString::asprintf("%02X", databuff[15])+"-"+QString::asprintf("%02X", databuff[16])+"-"+QString::asprintf("%02X", databuff[17])+"-"+QString::asprintf("%02X", databuff[18])+"-"+QString::asprintf("%02X", databuff[19])+"-"+QString::asprintf("%02X", databuff[20]); //MAC地址 ui- >listWidget_wifi- >addItem("WIFI_MAC地址:"+MACStr); QString GateWay=QString::asprintf("%d", databuff[21])+"."+QString::asprintf("%d", databuff[22])+"."+QString::asprintf("%d", databuff[23])+"."+QString::asprintf("%d", databuff[24]); //设备网关 ui- >listWidget_wifi- >addItem("WIFI网关地址:"+GateWay); QString GatewayMAC=QString::asprintf("%02X", databuff[25])+"-"+QString::asprintf("%02X", databuff[26])+"-"+QString::asprintf("%02X", databuff[27])+"-"+QString::asprintf("%02X", databuff[28])+"-"+QString::asprintf("%02X", databuff[29])+"-"+QString::asprintf("%02X", databuff[30]); //网关MAC ui- >listWidget_wifi- >addItem("网关 MAC地址:"+GatewayMAC); switch (databuff[31]){ case 0: ui- >listWidget_wifi- >addItem("WIFI网络状态:已连接wifi"); break; case 1: ui- >listWidget_wifi- >addItem("WIFI网络状态:连接失败!"); break; case 2: ui- >listWidget_wifi- >addItem("WIFI网络状态:已初始化!"); break; default: ui- >listWidget_wifi- >addItem("WIFI网络状态:未初始化!"); break; } QByteArray devname; for(int i=0 ;i< databuff[32];i++){ devname.append(databuff[34+i]); } QString devnamestr=devname; ui- >listWidget_wifi- >addItem("读卡器 名称:"+devnamestr); QByteArray wifname; for(int i=0 ;i< databuff[33];i++){ wifname.append(databuff[44+i]); } QString wifinamestr=wifname; ui- >listWidget_wifi- >addItem("WIFI热点名称:"+wifinamestr); } //更换不同的网卡---------------------------------------------------------------------------------------------------- void MainWindow::on_CBIP_currentIndexChanged(int index) { if (listening){ disconnect(udpSocket, &QUdpSocket::readyRead, this,&MainWindow::read_data); udpSocket- >close(); listening=false; listadditems(0,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 (currentRow< 0){ 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;i< 34;i++){ sendData.append(Dispbyte[i]); } SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //驱动设备蜂鸣响声----------------------------------------------------------------------------------------------------------- void MainWindow::on_PBbeep_clicked() { sendData.clear(); sendData.append(0x96); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 sendData.append(ui- >CBbeep- >currentIndex()); //蜂鸣响声代码 SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //驱动设备开启继电器---------------------------------------------------------------------------------------------------------- void MainWindow::on_PBSwitchOn_clicked() { sendData.clear(); sendData.append(0x78); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 QString swithno="F"+QString::asprintf("%d",ui- >CBSwitch- >currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //选择继电器 quint16 deltime=ui- >spinBox_swit- >value(); sendData.append(deltime % 256); //开启延时低位 sendData.append(deltime / 256); //开启延时高位 SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //驱动设备关闭继电器---------------------------------------------------------------------------------------------------------- void MainWindow::on_PBSwitchOff_clicked() { sendData.clear(); sendData.append(0x78); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 QString swithno="E"+QString::asprintf("%d",ui- >CBSwitch- >currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //选择继电器 quint16 deltime=ui- >spinBox_swit- >value(); sendData.append(deltime % 256); //延时低位 sendData.append(deltime / 256); //延时高位 SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //驱动设备显示文字+蜂鸣响声+播报TTS语音+开启继电器开关------------------------------------------------------------------------------ void MainWindow::on_PBSendDispTTS_clicked() { if(ui- >spinBox_voice- >value() >16){ui- >spinBox_voice- >setValue(16);} //tts最大语音取值16 QString strls="[v"+QString::asprintf("%d",ui- >spinBox_voice- >value())+"]"; strls=strls+ui- >textEdit_tts- >toPlainText().trimmed(); QByteArray SpeakArr=strls.toLocal8Bit(); //TS语音转换为Ansi码 quint8 speakbytes=SpeakArr.size(); quint8 dispbytes=34; //双行显示屏显示长度34,四行屏显示长度72 sendData.clear(); sendData.append(0x5c); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 sendData.append(ui- >CBbeep- >currentIndex()); //蜂鸣响声代码,取值255表示不响 QString swithno="F"+QString::asprintf("%d",ui- >CBSwitch- >currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //选择继电器 quint16 deltime=ui- >spinBox_swit- >value(); sendData.append(deltime % 256); //延时低位 sendData.append(deltime / 256); //延时高位 sendData.append(ui- >spinBox_dispdelay- >value()); //文字显示时长, quint8 begindisp =0; //在显示屏中的哪个位置开始显示,一般取0 sendData.append(begindisp); sendData.append(dispbytes); //显示文字长度 sendData.append(speakbytes); //tts语音长茺 QString dispstr=ui- >textEdit_disp- >toPlainText()+" "; //加空格是为了确保满屏34位显示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;i< dispbytes;i++){ sendData.append(Dispbyte[i]); //显示信息 } for(int i=0;i< speakbytes;i++){ sendData.append(SpeakArr[i]); //TTS语音信息 } sendData.append(0x55); //防干扰后缀 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //驱动设备显示文字+蜂鸣响声+播报固定组合语音+开启继电器开关------------------------------------------------------------------------------ void MainWindow::on_PBSendDispSpk_clicked() { QByteArray speakcode; //选择加入要播报的语音代码,最多可加入21个,各语音代码参看 语音列表栏 speakcode.append(36);speakcode.append(1);speakcode.append(11);speakcode.append(2);speakcode.append(10); speakcode.append(3);speakcode.append(17);speakcode.append(4);speakcode.append(16);speakcode.append(5);speakcode.append(15); qint8 lensy=speakcode.size(); //语音代码长度 quint8 begindisp =0; //在显示屏中的哪个位置开始显示,一般取0 quint8 dispbytes=34; //双行显示屏显示长度34 sendData.clear(); sendData.append(0x5b); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 sendData.append(ui- >CBbeep- >currentIndex()); //蜂鸣响声代码,取值255表示不响 QString swithno="F"+QString::asprintf("%d",ui- >CBSwitch- >currentIndex()); bool status; sendData.append(swithno.toUInt(&status,16)); //选择继电器 quint16 deltime=ui- >spinBox_swit- >value(); sendData.append(deltime % 256); //延时低位 sendData.append(deltime / 256); //延时高位 sendData.append(ui- >spinBox_dispdelay- >value()); //文字显示时长, sendData.append(begindisp); //显示起始位置 sendData.append(dispbytes); //显示字符串长度 sendData.append(lensy); //语音代码条数 QString dispstr=ui- >textEdit_disp- >toPlainText()+" "; //加空格是为了确保满屏34位显示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;i< dispbytes;i++){ sendData.append(Dispbyte[i]); //显示信息 } for(int i=0;i< lensy;i++){ sendData.append(speakcode[i]); //语音信息 } sendData.append(0x55); //防干扰后缀 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //指定扇区密钥读取M1卡扇区数据---------------------------------------------------------------------------------------- void MainWindow::on_PBReadCard_clicked() { unsigned char cardnobuf[4]; //卡号 unsigned char keybuf[6]; //密钥 int keylen; int cardnolen; QString cardnostr ="00000000"; // ui- >textEdit_M1UID- >toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen< 4){ QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!"); ui- >textEdit_M1UID- >setFocus(); return; } QString keyinf = ui- >textEdit_authkey- >toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen< 6){ QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!"); ui- >textEdit_authkey- >setFocus(); return; } sendData.clear(); sendData.append(0x3b); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 sendData.append(0x01); //本次操作的区数 for (int i=0 ;i< 4;i++){ //指定读写的卡号,全为0 表示可读写任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui- >CBPage- >currentIndex()); //本次操作的扇区号 sendData.append(ui- >CBauth- >currentIndex()); //为1以B密码来验证旧密码,为0以A密码来验证旧密码 for (int i=0 ;i< 6;i++){ sendData.append(keybuf[i]); //认证密钥 } SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } //指定扇区密钥写入数据到M1卡扇区---------------------------------------------------------------------------------------- void MainWindow::on_PBWriteCard_clicked() { unsigned char cardnobuf[4]; //卡号 unsigned char keybuf[6]; //密钥 int keylen; int cardnolen; int datalen; QString cardnostr ="00000000"; // ui- >textEdit_M1UID- >toPlainText().trimmed(); "00000000"表示可能操作感应区内任意卡,如要操作特定卡可指定卡号 cardnolen=MyClass::checkhexdata(cardnostr,cardnobuf); if(cardnolen< 4){ QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!"); ui- >textEdit_M1UID- >setFocus(); return; } QString keyinf = ui- >textEdit_authkey- >toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen< 6){ 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(datalen< 48){ int answ=QMessageBox::question (this, "警告", "有效的写卡数据不足一扇区48字节,是否要补0写入到指定扇区?", QMessageBox::Ok, QMessageBox::Cancel); if (answ !=1024){ ui- >textEdit_data- >setFocus(); return; } for (int i=datalen;i< 48;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 ;i< 4;i++){ //指定读写的卡号,全为0 表示可读写任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui- >CBPage- >currentIndex()); //本次操作的扇区号 sendData.append(ui- >CBauth- >currentIndex()); //为1以B密码来验证旧密码,为0以A密码来验证旧密码 for (int i=0 ;i< 6;i++){ sendData.append(keybuf[i]); //认证密钥 } for (int i=0 ;i< 48;i++){ sendData.append(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(cardnolen< 4){ QMessageBox::critical(NULL, "提示", "请输入8位正确的16进制卡号!"); ui- >textEdit_M1UID- >setFocus(); return; } QString keyinf = ui- >textEdit_authkey- >toPlainText().trimmed(); keylen=MyClass::checkhexdata(keyinf,keybuf); if(keylen< 6){ QMessageBox::critical(NULL, "提示", "请输入12位正确的16进制卡密码!"); ui- >textEdit_authkey- >setFocus(); return; } QString newkey = ui- >textEdit_newkey- >toPlainText().trimmed(); newkeylen=MyClass::checkhexdata(newkey,newkeybuf); if(newkeylen< 16){ QMessageBox::critical(NULL, "提示", "请输16进制 6字节A密码+4字节控制位+6字节B密码 !"); ui- >textEdit_newkey- >setFocus(); return; } sendData.clear(); sendData.append(0x3a); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 sendData.append(0x01); //本次操作的区数 for (int i=0 ;i< 4;i++){ //指定读写的卡号,全为0 表示可读写任意卡 sendData.append(cardnobuf[i]); } sendData.append(ui- >CBPage- >currentIndex()); //本次操作的扇区号 quint8 auth=ui- >CBauth- >currentIndex(); //为1以B密码来验证旧密码,为0以A密码来验证旧密码 auth=auth+ui- >ChangeKey- >currentIndex()*2; //修改A、B、控制位 sendData.append(auth); for (int i=0 ;i< 6;i++){ sendData.append(keybuf[i]); //认证密钥 } for (int i=0 ;i< 16;i++){ sendData.append(newkeybuf[i]); //新A密钥、控制位、B密钥 } sendData.append(0x55); //防干扰后缀 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } void MainWindow::on_PBSetRW_clicked() { 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 (row< 1){ return; }else{ for (int i=0;i< row;i++){ QListWidgetItem *item = ui- >listWidget- >item(i); listinf=listinf+item- >text()+"n"; } QClipboard *clipboard = QApplication::clipboard(); clipboard- >setText(listinf); QMessageBox::information(this, "提示", "显示数据报文已拷贝到剪切板"); } } //接收到刷卡数据立即回应-------------------------------------------------------------------------- void MainWindow::Respondinfo(QString Dispinf,QHostAddress ip,quint16 port,QString DeviceNumber) { QByteArray RespBuff; RespBuff.append(0x5A); //功能码 quint16 devno=DeviceNumber.toUInt(); RespBuff.append(devno % 256); //机号低位 RespBuff.append(devno / 256); //机号高位,高低位都为0表示所有机 RespBuff.append(ui- >CBbeep- >currentIndex()); //蜂鸣响声代码,255表示不响声 RespBuff.append(ui- >spinBox_dispdelay- >value()); //文字显示时长, QString dispstr=Dispinf+" "; //加空格是为了确保满屏34位显示 QByteArray Dispbyte=dispstr.toLocal8Bit(); for(int i=0;i< 34;i++){ RespBuff.append(Dispbyte[i]); } udpSocket- >writeDatagram(RespBuff.constData(), RespBuff.size(), QHostAddress(ip), port); QString SendHex=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 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } liststr = newmask.split("."); //掩码 for (int i=0 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } liststr = newserverip.split("."); //远程服务器IP for (int i=0 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } liststr = servermac.split("-"); //远程服务器MAC for (int i=0 ;i< 6;i++){ sendData.append(liststr[i].toInt(&ok,16)); } liststr = newgateway.split("."); //网关 for (int i=0 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } liststr = gatemac.split("-"); //网关MAC for (int i=0 ;i< 6;i++){ sendData.append(liststr[i].toInt(&ok,16)); } quint16 devno=ui- >New_Nember- >text().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 quint16 newport=ui- >New_Port- >text().toInt(); sendData.append(newport % 256); //端口低位 sendData.append(newport / 256); //端口高位 QString seri=ui- >Serial_Number- >text().trimmed(); liststr = seri.split("-"); //模块序号 for (int i=0 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } quint8 searchid=0; if (ui- >checkBox_beep- >isChecked()){searchid=searchid+1;} if (ui- >radioButton1- >isChecked()){searchid=searchid+2;} if (ui- >radioButton3- >isChecked()){searchid=searchid+4;} if (ui- >checkBox_dhcp- >isChecked()){searchid=searchid+8;} if (ui- >comboBox_out- >currentIndex()==1){searchid=searchid+16;} searchid=searchid+ ui- >comboBox_in- >currentIndex()*32; sendData.append(searchid); sendData.append(0x55); //防干扰后缀 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); if (ui- >checkBox_broadcast- >isChecked()){ //使用广播方式发送指令 QHostAddress broadcastAddress("255.255.255.255"); quint16 port1 = 39169; udpSocket- >writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1); QString dispinf=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;i< filebyte.size();i++){ sendData.append(filebyte[i]); //访问文件 crc=crc ^filebyte[i]; } sendData.append(crc); sendData.append(0x55); //防干扰后缀 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); if (ui- >checkBox_broadcast- >isChecked()){ //使用广播方式发送指令 QHostAddress broadcastAddress("255.255.255.255"); quint16 port1 = 39169; udpSocket- >writeDatagram(sendData.constData(), sendData.size(), QHostAddress::Broadcast, port1); QString dispinf=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 (currentRow< 0){ 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;i< wifiNamearry.size();i++){ sendData.append(wifiNamearry[i]); } quint8 bytebit=0; while (sendData.size()< 65){ sendData.append(bytebit); } for (i=0;i< passlen;i++){ sendData.append(wifipassarry[i]); } while (sendData.size()< 129){ sendData.append(bytebit); } if(ui- >radioButton_IP- >isChecked()){ sendData.append(1); QString ipstr=ui- >lineEdit_IP- >text().trimmed(); if (!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 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } liststr = mskstr.split("."); //掩码 for (int i=0 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } liststr = gatewaystr.split("."); //网关 for (int i=0 ;i< 4;i++){ sendData.append(liststr[i].toInt()); } }else{ sendData.append(bytebit); while (sendData.size()< 142){ sendData.append(bytebit); } } sendData.append(ui- >comboBox_Sendmode- >currentIndex()); sendData.append(0x55); //防干扰后缀 sendData.append(0xaa); sendData.append(0x66); sendData.append(0x99); SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } void MainWindow::on_pushButton_Read_clicked() { ui- >listWidget_wifi- >clear(); sendData.clear(); sendData.append(0xa4); //功能码 quint16 devno=ui- >textEdit_DeviceNumber- >toPlainText().toUInt(); sendData.append(devno % 256); //机号低位 sendData.append(devno / 256); //机号高位,高低位都为0表示所有机 SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } 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;i< 16;i++){ QCheckBox *myCheckBox = this- >findChild< QCheckBox * >("checkBox_s"+QString::asprintf("%d",i)); QComboBox *myComboBox = this- >findChild< QComboBox * >("CBauth_"+QString::asprintf("%d",i)); QTextEdit *myTextEdit = this- >findChild< QTextEdit * >("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(keylen< 6){ 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;p< 6;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 (currentRow< 0){ QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok); }else{ QString writehex = ui- >textEdit_data- >toPlainText().trimmed(); writehex=writehex.replace(" ",""); int j=MyClass::checkhexdata(writehex,writecardbuf); if((j< 1) || (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;i< 4;i++){ //加入4个字节的卡号,卡号为0表示可以操作任意卡 sendData.append(1-1); } for (int i=0;i< j*48;i++){ sendData.append(writecardbuf[writcarepoi*48+i]); } SendBuffAct(); //将sendData缓冲数据发送到指定的设备IP端口 } } } 审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !