Qt C++ TCP服务端响应多客户端通讯

本示例使用的设备:WIFI无线4G网络RFID云读卡器远程网络开关物流网阅读器TTS语音-淘宝网 (taobao.com)

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QMessageBox"
#include <QDebug>
#include <exception>
#include <QTcpServer>
#include <QTcpSocket>
#include <QObject>
#include <QTime>
#include <QTreeWidgetItem>
#include <QClipboard>bool listening=false;
QTcpServer m_server;
QTcpSocket m_socket;//获取本机所有网卡IP------------------------------------------------------------------------------------------------------
QStringList getAllIPAddresses() {QStringList ips;QList<QHostAddress> list = QNetworkInterface::allAddresses();for (int i = 0; i < list.size(); ++i) {QHostAddress address = list.at(i);// 检查是否为IPv4地址,并排除回环地址if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress::LocalHost) {ips << address.toString();}}return ips;
}//获取系统现时间-------------------------------------------------------------------------------------------------------------
QString getsystime(){QTime time = QTime::currentTime();QString timeStr = time.toString("hh:mm:ss.zzz");return timeStr;
}//获取系统日期时间-------------------------------------------------------------------------------------------------------------
QString getsysdatetime(){QDateTime currentDateTime = QDateTime::currentDateTime();QString dateTimeString = currentDateTime.toString("yy-MM-dd hh:mm:ss");return dateTimeString;
}//QByteArray转16进制QString------------------------------------------------------------------------------------------------
QString ByteArrayToHexString(QByteArray data){QString ret(data.toHex().toUpper());int len = ret.length()/2;for(int i=1;i<len;i++){ret.insert(2*i+i-1," ");}return ret;
}//通讯报文显示-----------------------------------------------------------------------------------------------------
void MainWindow::listadditems(int ctr,QString listinfo){switch (ctr){case 0:if(ui->listWidget_report->count()>30){ui->listWidget_report->clear();}ui->listWidget_report->addItem(listinfo);ui->listWidget_report->setCurrentRow(ui->listWidget_report->count()-1);break;case 1:ui->listWidget_online->addItem(listinfo);ui->listWidget_online->setCurrentRow(ui->listWidget_online->count()-1);}
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);ui->TEPort->setPlainText("39169");        //出厂默认39169端口ui->spinBox_dispdelay->setValue(20);ui->spinBox_swit->setValue(30);ui->spinBox_voice->setValue(8);ui->textEdit_disp->setText("欢迎您使用我们的网络读卡器!");ui->textEdit_tts->setText("感谢您的使用,您的支持是我们最大的动力!");QStringList ips = getAllIPAddresses();foreach (QString ip, ips) {ui->CBIP->addItem(ip);}if(ui->CBIP->count()<1){QMessageBox::information(NULL, "提示", "未搜索到本机的网卡,系统不能正常运行!");delete ui;}
}MainWindow::~MainWindow()
{delete ui;
}//启动、关闭TCP服务-------------------------------------------------------------------------------------------------------
void MainWindow::initserver(){try{if(ui->pushButton_initserver->text()=="开启TCP服务"){QString ipstr=ui->CBIP->currentText();QHostAddress localeip(ipstr);quint16 port=ui->TEPort->toPlainText().toUInt();m_server = new QTcpServer(this);m_server->listen(localeip, port);connect(m_server, &QTcpServer::newConnection, this, &MainWindow::onNewConnection);listening=true;ui->pushButton_initserver->setText("停止");listadditems(0,getsystime()+" Tcp Server is listening...");}else{listening=false;m_server->close();ui->pushButton_initserver->setText("开启TCP服务");for(int i=0;i<tcpclientlist.count();i++){tcpclientlist.at(i)->close();//tcpclientlist.remove(i);ui->listWidget_online->takeItem(i);}tcpclientlist.clear();listadditems(0,getsystime()+" Tcp Server is close! ");}}catch(_exception){listening=false;ui->pushButton_initserver->setText("开启TCP服务");}
}//侦听到有新的TCP客户端接入服务--------------------------------------------------------------------------------------------
void MainWindow::onNewConnection()
{m_socket = m_server->nextPendingConnection();tcpclientlist.append(m_socket);QString RemoIp=m_socket->peerAddress().toString();QString RemoPort=QString::number( m_socket->peerPort());listadditems(1,RemoIp+":"+RemoPort);listadditems(0,getsystime()+" NewConn "+RemoIp+":"+RemoPort);connect(m_socket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead);connect(m_socket, &QTcpSocket::disconnected, this, &MainWindow::onClientDisconnected);connect(m_socket, &QTcpSocket::connected, this, &MainWindow::onConnected);
//  connect(m_socket, &QTcpSocket::stateChanged, this, &MainWindow::onStateChanged);}//接收到TCP客户端传送来来的数据-------------------------------------------------------------------------------------------
void MainWindow::onReadyRead()
{QByteArray buffer;for(int row=0;row<tcpclientlist.count();row++){m_socket=tcpclientlist.at(row);buffer = m_socket->readAll();if(buffer.length()!=0){QString RemoIp=m_socket->peerAddress().toString();QString RemoPort=QString::number( m_socket->peerPort());listadditems(0,getsystime()+" Receive: "+RemoIp+":"+RemoPort+"    "+ByteArrayToHexString(buffer));unsigned char databuff[buffer.length()];std::copy(buffer.begin(), buffer.end(), databuff);switch (databuff[0]){case 0xc1:case 0xcf:Analyze_c1_cf(row,databuff,buffer.length());          //解析读取IC卡卡号break;case 0xd1:case 0xdf:Analyze_d1_df(row,databuff,buffer.length());          //解析读取ID卡卡号break;default:break;}}}
}//侦测到TCP客户端断开连接---------------------------------------------------------------------------------------------
void MainWindow::onClientDisconnected()
{QString RemoIp=m_socket->peerAddress().toString();quint16 RemoPort= m_socket->peerPort();for(int i=0;i<tcpclientlist.count();i++){if(tcpclientlist.at(i)->peerAddress().toString()==RemoIp && tcpclientlist.at(i)->peerPort()==RemoPort){tcpclientlist.remove(i);ui->listWidget_online->takeItem(i);listadditems(0,getsystime()+" Disconn: "+RemoIp+":"+QString::number(RemoPort));}}
}void MainWindow::onConnected()
{QString RemoIp=m_socket->peerAddress().toString();QString RemoPort=QString::number( m_socket->peerPort());
}//void MainWindow::onStateChanged(QAbstractsocket::SocketState socketstate){
//    switch (socketstate){
//    case QAbstractSocket::UnconnectedState:ui->labConnectState->setText("Unconnectedstate");break;
//    case QAbstractSocket::HostLookupState:ui->labConnectState->setText("HostLookupstate");break;
//    case QAbstractSocket::ConnectedState:ui->labConnectState->setText("connectedstate");break;
//    case QAbstractSocket::ConnectingState:ui->labConnectState->setText("connectingstate");break;
//    case QAbstractSocket::BoundState: ui->labConnectState->setText("Boundstate");break;
//    case QAbstractSocket::ClosingState:ui->labConnectState->setText("closingstate");break;
//    case QAbstractSocket::ListeningState:ui->labConnectState->setText("listeningstate");break;
//    }
//}//解析读取IC卡卡号-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_c1_cf(int socketid,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 FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号int cardnolen=databuff[9];QString CardnoHexZ="";          //16进制卡号正码QString CardnoHexF="";          //16进制卡号反码for (int i=0;i<cardnolen;i++){CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[10+i]);if(i<4){CardnoHexF=CardnoHexF+QString::asprintf("%02X", databuff[9+cardnolen-i]);}   //只取4个字节计算8H10D反码}QString SerialNumber="";        //设备全球唯一硬件序号for (int i=10+cardnolen;i<buflen;i++){SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);}bool status;QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //转8H10D反码卡号QString  DispInf;if (databuff[0]==0xc1){DispInf="读取IC卡号,";}else{DispInf="IC卡离开读卡器,";}DispInf=DispInf+"设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;ui->plainTextEdit_msg->setPlainText(DispInf);if(ui->checkBox_Resp->isChecked()){Respondinfo(socketid,getsysdatetime()+"卡号:"+Cardno8H10D);}  //回应驱动设备显示+蜂鸣响声
}//解析读取ID卡卡号-------------------------------------------------------------------------------------------------------------------
void MainWindow::Analyze_d1_df(int socketid,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 FrameNumber=QString::asprintf("%05d",databuff[7]+databuff[8]*256);    //数据包号QString CardnoHexZ="";          //16进制卡号正码QString CardnoHexF="";          //16进制卡号反码for (int i=0;i<5;i++){CardnoHexZ=CardnoHexZ+QString::asprintf("%02X", databuff[9+i]);if(i<4){CardnoHexF=CardnoHexF+QString::asprintf("%02X", databuff[9+3-i]);}   //只取4个字节计算8H10D反码}QString SerialNumber="";        //设备全球唯一硬件序号for (int i=9+5;i<buflen;i++){SerialNumber=SerialNumber+QString::asprintf("%02X", databuff[i]);}bool status;QString Cardno8H10D=QString::asprintf("%010u",CardnoHexF.toUInt(&status,16));  //转8H10D反码卡号QString  DispInf;if (databuff[0]==0xd1){DispInf="读取ID卡号,";}else{DispInf="ID卡离开读卡器,";}DispInf=DispInf+"设备IP:"+IPAddress+",机号:"+DeviceNumber+",数据包号:"+FrameNumber+",16进制卡号:"+CardnoHexZ+",转8H10D反码:"+Cardno8H10D+",设备全球唯一序号:"+SerialNumber;ui->plainTextEdit_msg->setPlainText(DispInf);if(ui->checkBox_Resp->isChecked()){Respondinfo(socketid,getsysdatetime()+"卡号:"+Cardno8H10D);}  //回应驱动设备显示+蜂鸣响声
}void MainWindow::on_btnClose_clicked()
{m_server->close();
}//向指定的客户端发送数据--------------------------------------------------------------------------------------------------------------
void MainWindow::SendBufToSockID(int socketid,QByteArray rbuffer){m_socket=tcpclientlist.at(socketid);m_socket->write(rbuffer);QString RemoIp=m_socket->peerAddress().toString();QString RemoPort=QString::number( m_socket->peerPort());QString SendHex=getsystime()+" Send To: "+(RemoIp+":"+RemoPort+"             ").mid(0,22);SendHex=SendHex+ByteArrayToHexString(rbuffer);listadditems(0,SendHex);
}void MainWindow::on_pushButton_initserver_clicked()
{initserver();
}//驱动读卡器蜂鸣响声-----------------------------------------------------------------------
void MainWindow::on_btnSendbeep_clicked()
{QListWidgetItem *item = ui->listWidget_online->currentItem();int row = ui->listWidget_online->row(item);if(row<0){QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);}else{QByteArray sendData;sendData.append(0x96);                             //功能码quint16 devno=0;sendData.append(devno % 256);                      //机号低位sendData.append(devno / 256);                      //机号高位,高低位都为0表示任意机号sendData.append(ui->CBbeep->currentIndex());       //蜂鸣响声代码SendBufToSockID(row,sendData);}
}//驱动读卡器开启继电器-----------------------------------------------------------------------
void MainWindow::on_btnswitchon_clicked()
{QListWidgetItem *item = ui->listWidget_online->currentItem();int row = ui->listWidget_online->row(item);if(row<0){QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);}else{QByteArray sendData;sendData.append(0x78);                             //功能码quint16 devno=0;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);                    //开启延时高位SendBufToSockID(row,sendData);}
}//驱动读卡器关闭已开启的继电器-----------------------------------------------------------------
void MainWindow::on_btnswitchoff_clicked()
{QListWidgetItem *item = ui->listWidget_online->currentItem();int row = ui->listWidget_online->row(item);if(row<0){QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);}else{QByteArray sendData;sendData.append(0x78);                             //功能码quint16 devno=0;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);                    //开启延时高位SendBufToSockID(row,sendData);}
}//驱动读卡器蜂鸣响声并显示文字---------------------------------------------------------------------
void MainWindow::on_btnDispbeep_clicked()
{QListWidgetItem *item = ui->listWidget_online->currentItem();int row = ui->listWidget_online->row(item);if(row<0){QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);}else{QByteArray sendData;sendData.append(0x5A);                             //功能码quint16 devno=0;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]);}SendBufToSockID(row,sendData);}
}//驱动读卡器蜂鸣响声+显示文字+播报TTS语音+开启继电器开关
void MainWindow::on_btndispbeeptts_clicked()
{QListWidgetItem *item = ui->listWidget_online->currentItem();int row = ui->listWidget_online->row(item);if(row<0){QMessageBox::critical(this, "警告", "请选择一台在线设备再执行此功能!", QMessageBox::Ok);}else{if(ui->spinBox_voice->value()>16){ui->spinBox_voice->setValue(16);} //tts最大语音取值16QString 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,四行屏显示长度72QByteArray sendData;sendData.append(0x5c);                             //功能码quint16 devno=0;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;                               //在显示屏中的哪个位置开始显示,一般取0sendData.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);SendBufToSockID(row,sendData);}
}//接收到刷卡数据立即回应--------------------------------------------------------------------------
void MainWindow::Respondinfo(int socketid,QString Dispinf)
{QByteArray RespBuff;RespBuff.append(0x5A);                             //功能码quint16 devno=0;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]);}m_socket=tcpclientlist.at(socketid);m_socket->write(RespBuff);QString RemoIp=m_socket->peerAddress().toString();QString RemoPort=QString::number( m_socket->peerPort());QString SendHex=getsystime()+" Send To: "+(RemoIp+":"+RemoPort+"             ").mid(0,22);SendHex=SendHex+ByteArrayToHexString(RespBuff);listadditems(0,SendHex);
}void MainWindow::on_btncopyreport_clicked()
{QString listinf;int row=ui->listWidget_report->count();if (row<1){return;}else{for (int i=0;i<row;i++){QListWidgetItem *item = ui->listWidget_report->item(i);listinf=listinf+item->text()+"\n";}QClipboard *clipboard = QApplication::clipboard();clipboard->setText(listinf);QMessageBox::information(this, "提示", "显示数据报文已拷贝到剪切板");}
}

源码下载 :https://download.csdn.net/download/zhangjin7422/89421064

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qemu创建kvm虚拟机-x86模拟arm

1、虚拟机环境 虚拟机ubuntu22.042、下载需要的依赖 apt install openssh-server net-tools vim -yapt install qemu qemu-kvm qemu-system-arm bridge-utils uml-utilities qemu-efi-aarch64 cloud-image-utils -y#查看版本 qemu-img -V(1) 下载uefi固件 cd /optwget https…

[大模型]LLaMA3-8B-Instruct Lora 微调

本节我们简要介绍如何基于 transformers、peft 等框架&#xff0c;对 LLaMA3-8B-Instruct 模型进行 Lora 微调。Lora 是一种高效微调方法&#xff0c;深入了解其原理可参见博客&#xff1a;知乎|深入浅出 Lora。 这个教程会在同目录下给大家提供一个 nodebook 文件&#xff0c…

服务器如何远程桌面连接不上,服务器远程桌面连接不上解决办法

服务器远程桌面连接不上&#xff0c;是IT运维中常见的挑战之一。针对这一问题&#xff0c;专业的解决方法通常涉及以下几个方面的排查与操作&#xff1a; 首先&#xff0c;我们需要检查网络连接是否正常。远程桌面连接依赖于稳定的网络连接&#xff0c;因此&#xff0c;确认服务…

【云原生】创建harbor私有仓库及使用aliyun个人仓库

1.安装docker #删除已有dockersystemctl stop docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine #安装docker yum install -y docker-ce-20.10.1…

企业级开源项目,云缓存解决方案:CacheCloud

CacheCloud&#xff1a;简化缓存管理&#xff0c;释放数据潜力- 精选真开源&#xff0c;释放新价值。 概览 CacheCloud是由搜狐视频团队开发的一款开源的Redis缓存云平台&#xff0c;支持Redis多种架构(Standalone、Sentinel、Cluster)高效管理、有效降低大规模redis运维成本&…

8.transformers量化

Transformers 核心设计Auto Classes Transformers Auto Classes 设计:统一接口、自动检索 AutoClasses 旨在通过全局统一的接口 from_pretrained() ,实现基于名称(路径)自动检索预训练权重(模 型)、配置文件、词汇表等所有与模型相关的抽象。 灵活扩展的配置AutoConfig…

webshell三巨头 综合分析(蚁剑,冰蝎,哥斯拉)

考点: 蚁剑,冰蝎,哥斯拉流量解密 存在3个shell 过滤器 http.request.full_uri contains "shell1.php" or http.response_for.uri contains "shell1.php" POST请求存在明文传输 ant 一般蚁剑执行命令 用垃圾字符在最开头填充 去掉垃圾字符直到可以正常bas…

Bankless:为什么 AI 需要 Crypto 的技术?

原文标题&#xff1a;《Why AI Needs Crypto’s Values》 撰文&#xff1a;Arjun Chand&#xff0c;Bankless 编译&#xff1a;Chris&#xff0c;Techub News 原文来自香港Web3媒体&#xff1a;Techub News 人工智能革命的梦想一直是一把双刃剑。 释放人工智能的潜力可以解…

世优科技AI数字人多模态交互系统“世优波塔”正式发布

2024年6月6日&#xff0c;世优科技“波塔发布会”在北京举办&#xff0c;本次发布会上&#xff0c;世优科技以全新的“波塔”产品诠释了更高效、更智能、更全面的AI数字人产品及软硬件全场景解决方案&#xff0c;实现了世优品牌、产品和价值的全面跃迁。来自行业协会、数字产业…

AIGC简介

目录 1.概述 2.诞生背景 3.作用 4.优缺点 4.1.优点 4.2.缺点 5.应用场景 5.1.十个应用场景 5.2.社交媒体内容 6.如何使用 7.未来展望 8.总结 1.概述 AIGC 是“人工智能生成内容”&#xff08;Artificial Intelligence Generated Content&#xff09;的缩写&#x…

【计算机网络】P3 计算机网络协议、接口、服务的概念、区别以及计算机网络提供的三种服务方式

目录 协议什么是协议协议是水平存活的协议的组成 接口服务服务是什么服务原语 协议与服务的区别计算机网络提供的服务的三种方式面向连接服务与无连接服务可靠服务与不可靠服务有应答服务与无应答服务 协议 什么是协议 协议&#xff0c;就是规则的集合。 在计算机网络中&…

33 _ 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

通过上篇文章的介绍&#xff0c;我们知道了同源策略可以隔离各个站点之间的DOM交互、页面数据和网络通信&#xff0c;虽然严格的同源策略会带来更多的安全&#xff0c;但是也束缚了Web。这就需要在安全和自由之间找到一个平衡点&#xff0c;所以我们默认页面中可以引用任意第三…

ARM32开发--PWM高级定时器

目录 文章目录 前言 目标 学习内容 需求 高级定时器通道互补输出 开发流程 通道配置 打开互补保护电路 完整代码 练习题 总结 前言 在嵌入式软件开发中&#xff0c;PWM&#xff08;脉冲宽度调制&#xff09;技术被广泛应用于控制各种电子设备的亮度、速度等参数。…

大疆智图_空三二维重建成果传输

一、软件环境 1.1 所需软件 1、 大疆智图&#xff1a;点击下载&#xff1b;   2、 ArcGIS Pro 3.1.5&#xff1a;点击下载&#xff0c;建议使用IDM或Aria2等多线程下载器&#xff1b;   3、 IDM下载器&#xff1a;点击下载&#xff0c;或自行搜索&#xff1b;   4、 Fas…

攻防演练之-网络安全产品大巡礼二

书接上文&#xff0c;《网络安全攻防演练风云》专栏之攻防演练之-网络安全产品大巡礼一&#xff0c;这里。 “咱们中场休息一会&#xff0c;我去接杯水哈”&#xff0c;看着认真听讲的众人&#xff0c;王工很是满意&#xff0c;经常夹在甲乙两方受气的他&#xff0c;这次终于表…

VBA即用型代码手册:删除空列Delete Empty Columns

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

面试题:ArrayList和LinkedList的区别

ArrayList和LinkedList都是Java中实现List接口的集合类&#xff0c;用于存储和操作对象列表&#xff0c;但它们在内部数据结构、性能特性和适用场景上有所不同&#xff1a; 1.内部数据结构&#xff1a; ArrayList&#xff1a;基于动态数组实现。这意味着它在内存中是连续存储…

鸿蒙元服务未来是能一“通”多端的前端形态?

2024年&#xff0c;华为鸿蒙的热度只增不减。 在2023年底就有业内人士透露&#xff0c;华为明年将推出不兼容安卓的鸿蒙版本&#xff0c;未来IOS、鸿蒙、安卓将成为三个各自独立的系统。 果不其然&#xff0c;执行力超强的华为&#xff0c;与2024年1月18日的开发者&#xff0…

web刷题记录(5)

[羊城杯 2020]easycon 进来以后就是一个默认测试页面&#xff0c; 在这种默认界面里&#xff0c;我觉得一般不会有什么注入点之类的&#xff0c;所以这里先选择用御剑扫扫目录看看有没有什么存在关键信息的页面 扫了一半发现&#xff0c;很多都是和index.php文件有关&#xff0…

C# Winform内嵌窗体(在主窗体上显示子窗体)

在开发Winform项目中&#xff0c;经常会要切换不同的窗体。通常程序都有一个主窗体&#xff0c;在切换窗体时往往需要关闭其他子窗体&#xff0c;这个实例就来介绍MDI主窗体内嵌子窗体的实现方法。 MDI主窗体要设置一个比较重要的属性&#xff0c;IsMdiContainertrue。子窗体的…