当前位置: 首页 > news >正文

Qt——TCP UDP网络编程

目录

  • 前言
  • 正文
    • 一、TCP
    • 二、UDP
      • 1、基本流程
      • 2、必备知识
    • 三、代码层级
      • 1、UDP服务端
    • END、总结的知识与问题
      • 1、如何获取QByteArray中某一字节的数据,并将其转为十进制?
      • 2、如何以本年本月本日为基础,获取时间戳,而不以1970为基础?
      • 3、如何将一个四个字节组成的数拆分成1个字节一个字节的?
      • 4、如何对前面的所有字节进行异或校验?
      • 5、如何将QByteArray中的某个字节转为十六进制?
  • 参考

前言

恰好,有个项目需要用到UDP,之前使用比较多的是TCP,UDP的还是第一次搞,但是感觉流程也是差不多,甚至比TCP要更简单就行,这里就稍微做一下总结,写一下自己需要注意的点,以及从网上查找到的,比较有用的一些资料。本篇文章,主要偏向的还是UDP,TCP的话,大家可以稍微看下,当做过下眼。

正文

一、TCP

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输协议,它是OSI(Open System Interconnection,开放式系统互联)模型中的第四层协议,通常使用于网络中的应用层和传输层之间。

​ TCP建立连接主要就是三次握手、断开连接主要就是四次挥手。

三次握手的基本流程如下:
在这里插入图片描述
四次挥手的基本流程如下:

在这里插入图片描述

关于TCP Socket 的实现逻辑如下:

在这里插入图片描述
本篇文章关于TCP就点到为止了。下面就讲下UDP了。

二、UDP

1、基本流程

UDP(User Data Protocol),用户数据报协议,是一种简单轻量级、不可靠、面向数据报、无连接的传输层协议,可以应用在可靠性不是十分重要的场合,如短消息、广播信息等。

适用于以下几种情况:

A、网络数据大多为短消息。

B、拥有大量客户端

C、对数据安全性无特殊要求

D、网络负担非常重,但对响应速度要求高。

这部分内容,应该有一部分难点在于UDP的拆包上面,但由于目前解除的项目不需要拆包,就暂不考虑这个问题了。

UDP编程的流程:

在这里插入图片描述
在这里插入图片描述

2、必备知识

1、数据报的长度一般不少于512字节,每个数据报包含发送者和接收者的IP地址和端口等信息。
2、单播、广播、组播的知识

单播(unicast)模式:一个UDP客户端发出的数据报只发送到另一个指定地址和端口的UDP客户端,是一对一的数据传输。
广播(broadcast)模式:一个UDP客户端发出的数据报,在同一网络范围内其他所有的UDP客户端都可以收到。QUdpSocket支持IPv4广播。广播经常用于实现网络发现的协议。要获取广播数据只需在数据报中指定接收端地址为QHostAddress::Broadcast,一般的广播地址为255.255.255.255。
组播(multicast)模式:也称为多播。UDP客户端加入到另一组播IP地址指定的多播组,成员向多组播地址发送的数据报组内成员都可以接收到,类似于QQ群的功能。

  1. 单播(Unicast):单播是一种点对点的通信方式,其中一个发送方(源)向一个接收方(目标)发送数据。在单播通信中,数据从发送方经过网络传输到指定的接收方,其他设备不会接收到该数据。单播适用于需要将数据传输到特定设备或主机的场景,例如客户端-服务器通信。

  2. 广播(Broadcast):广播是一种一对多的通信方式,其中一个发送方向局域网中的所有设备发送数据。在广播通信中,数据从发送方通过网络传输到同一局域网中的所有设备。所有接收方都会接收到广播数据。广播适用于需要将数据传输到局域网中的所有设备的场景,例如局域网上的服务发现、网络广告等。

  3. 广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机。值得强调的是:本地广播信息是不会被路由器转发。当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。

    其实广播顾名思义,就是想局域网内所有的人说话,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。
    3、报文大小的限制与各系统的协议实现有关,但不得超过其下层 IP 协议规定的64KB
    4、所谓客户端进行广播,是指客户端向一个广播地址255.255.255.255 + 一个指定的服务端监听的端口号 进行发送数据。只要端口号是对的,那么服务端就会接收到数据。
    5、如何监听某个端口:netstat -ano | findstr 1024
    6、在这里插入图片描述

三、代码层级

1、UDP服务端

该代码是我实现的UDP服务端,只负责接收信息。
UDPServer.h

#ifndef UDPSERVER_H
#define UDPSERVER_H#include <QObject>
#include <QUdpSocket>class CUdpServer : public QObject
{Q_OBJECTpublic:explicit CUdpServer(QObject *parent = nullptr);~CUdpServer();bool OpenUdpServer(const int &_iPort);
protected:bool _WriteDatagram(const QString &_sIp, const int &_iPort, char *_pData, int _iLength);bool _ResponseFrame(const QString &_sIp, const int &_iPort, const QString &_sCmd, const QByteArray &_oArray);bool _HandleLoginFrame(const QString &_sIp, const int &_iPort, const QByteArray &_oArray);
private:void _Init();uint8_t _XorCheck(uint8_t *pbuf, uint32_t length);qint64 _GetNowDateTimeStampMs();public slots:void on_readyRead();
private:QUdpSocket* m_pUdpServer = nullptr;bool m_bOpen = false;bool m_bDoing = false;int m_iElectricQuantity = 0;
};#endif // UDPSERVER_H

UDPServer.cpp

#include "UdpServer.h"#include <QNetworkDatagram>
#include <QDateTime>#include <CommonFunc.h>
#include <KldLog.h>CUdpServer::CUdpServer(QObject *parent):QObject(parent)
{_Init();connect(m_pUdpServer, &QUdpSocket::readyRead, this, &CUdpServer::on_readyRead);
}CUdpServer::~CUdpServer()
{}bool CUdpServer::OpenUdpServer(const int &_iPort)
{bool bRet = false;if (false == m_bOpen){bRet = m_pUdpServer->bind(QHostAddress::Any, _iPort);if (bRet){m_bOpen = true;}}return bRet;
}bool CUdpServer::_WriteDatagram(const QString &_sIp, const int &_iPort, char *_pData, int _iLength)
{bool bRet = false;QByteArray oOutputArray = QByteArray::fromRawData((char*)_pData, _iLength);qint64 iLen = m_pUdpServer->writeDatagram(oOutputArray, QHostAddress(_sIp), _iPort);return bRet;
}bool CUdpServer::_ResponseFrame(const QString &_sIp, const int &_iPort, const QString &_sCmd, const QByteArray &_oArray)
{bool bRet = false;int iElectricQuantity = (int)_oArray.at(3);uchar cArray[16]= {0};cArray[0] = 0xAF;//帧头cArray[1] = 0x00;//设备类型cArray[2] = 0x00;//设备编号cArray[3] = 0x64;//电池电量qint64 iTimeStamp = _GetNowDateTimeStampMs();quint8 byte1 = (iTimeStamp >> 24) & 0xFF;quint8 byte2 = (iTimeStamp >> 16) & 0xFF;quint8 byte3 = (iTimeStamp >> 8) & 0xFF;quint8 byte4 = iTimeStamp & 0xFF;LOG_INFO << "--->z CUdpServer::_HandleHeartFrame byte1:"<< iTimeStamp<<"||"<<QString::number(iTimeStamp, 16).toStdString();cArray[4] = (int)byte1;//时间戳cArray[5] = (int)byte2;//时间戳cArray[6] = (int)byte3;//时间戳cArray[7] = (int)byte4;//时间戳cArray[8] = _oArray.at(8);//唯一IDcArray[9] = _oArray.at(9);//唯一IDcArray[10] = _oArray.at(10);//唯一IDcArray[11] = _oArray.at(11);//唯一IDbool bOK = false;cArray[12] = _sCmd.toInt(&bOK, 16);//命令类型cArray[13] = 0x00;//包序列cArray[14] = 0x00;//数据长度cArray[15] = _XorCheck(cArray, sizeof(cArray) - 1);//校验字节bRet = _WriteDatagram(_sIp, _iPort, (char*)cArray, sizeof(cArray));return bRet;
}bool CUdpServer::_HandleLoginFrame(const QString &_sIp, const int &_iPort, const QByteArray &_oArray)
{bool bRet = false;if (_oArray.length() < 16){return bRet;}if (m_bDoing){return false;}m_bDoing = true;bRet = _ResponseFrame(_sIp, _iPort, "01", _oArray);m_bDoing = false;return bRet;
}void CUdpServer::_Init()
{m_pUdpServer = new QUdpSocket(this);
}uint8_t CUdpServer::_XorCheck(uint8_t *pbuf, uint32_t length)
{uint8_t temp = 0;uint32_t i;pbuf++;pbuf++;for (i = 0; i < length - 2; i++){temp ^= *pbuf++;}return temp;
}qint64 CUdpServer::_GetNowDateTimeStampMs()
{// 获取当前日期和时间QDateTime currentDateTime = QDateTime::currentDateTime();// 获取当前年份int iCurrentYear = currentDateTime.date().year();int iCurrentMonth = currentDateTime.date().month();int iCurrentDay = currentDateTime.date().day();// 创建基准日期(以当前年份为基准)QDateTime baseDateTime(QDate(iCurrentYear, iCurrentMonth, iCurrentDay), QTime(0, 0, 0));// 计算当前时间相对于基准日期的毫秒数qint64 timestamp = currentDateTime.toMSecsSinceEpoch() - baseDateTime.toMSecsSinceEpoch();return timestamp;
}void CUdpServer::on_readyRead()
{//帧头(af)   设备类型    设备编号    电池电量  时间戳     唯一ID    命令类型  包序列  数据长度   校验字节    数据校验    数据// 1           1          1          1      4          4        1       1       1         1         1         Nwhile (m_pUdpServer->hasPendingDatagrams())                       // 判断是否有可读数据{QNetworkDatagram datagram = m_pUdpServer->receiveDatagram(); // 读取数据QByteArray replyData = datagram.data();if(replyData.count()){QString sIP = datagram.senderAddress().toString().remove("::ffff:");int iPort = datagram.senderPort();QString sCmd = QString("%1").arg((char)replyData.at(12), 2, 16, QChar('0'));for (int i = 0; i< replyData.size(); i++){char byte = replyData.at(i);QString sByte = QString::number((int)byte, 16);QString hexString = QString("%1").arg((int)byte, 2, 16, QChar('0'));}if (sCmd == "01"){_HandleLoginFrame(sIP, iPort, replyData);}}}
}

调用的时候,就直接new一个这个UDPServer的对象就可以了。

如果大家需要直接可以运行起来的程序,大家可以参考这位兄弟的,这位兄弟的就写的比较完整了,客户端,服务端都有。
https://github.com/mahuifa/QMDemo/tree/master/QMNetwork

END、总结的知识与问题

1、如何获取QByteArray中某一字节的数据,并将其转为十进制?

int iElectricQuantity = (int)_oArray.at(3);

2、如何以本年本月本日为基础,获取时间戳,而不以1970为基础?

qint64 CUdpServer::_GetNowDateTimeStampMs()
{// 获取当前日期和时间QDateTime currentDateTime = QDateTime::currentDateTime();// 获取当前年份int iCurrentYear = currentDateTime.date().year();int iCurrentMonth = currentDateTime.date().month();int iCurrentDay = currentDateTime.date().day();// 创建基准日期(以当前年份为基准)QDateTime baseDateTime(QDate(iCurrentYear, iCurrentMonth, iCurrentDay), QTime(0, 0, 0));// 计算当前时间相对于基准日期的毫秒数qint64 timestamp = currentDateTime.toMSecsSinceEpoch() - baseDateTime.toMSecsSinceEpoch();return timestamp;
}

3、如何将一个四个字节组成的数拆分成1个字节一个字节的?

 	qint64 iTimeStamp = _GetNowDateTimeStampMs();//这个实际获取到的是4个字节,但也没关系,我们根据下面的方式,取到的一定是最前面的四个字节quint8 byte1 = (iTimeStamp >> 24) & 0xFF;quint8 byte2 = (iTimeStamp >> 16) & 0xFF;quint8 byte3 = (iTimeStamp >> 8) & 0xFF;quint8 byte4 = iTimeStamp & 0xFF;cArray[4] = (int)byte1;//时间戳cArray[5] = (int)byte2;//时间戳cArray[6] = (int)byte3;//时间戳cArray[7] = (int)byte4;//时间戳

4、如何对前面的所有字节进行异或校验?

uint8_t CUdpServer::_XorCheck(uint8_t *pbuf, uint32_t length)
{uint8_t temp = 0;uint32_t i;pbuf++;pbuf++;for (i = 0; i < length - 2; i++){temp ^= *pbuf++;}return temp;
}

5、如何将QByteArray中的某个字节转为十六进制?

char byte = replyData.at(i);//replayData就是一个QByteArray
QString hexString = QString("%1").arg((int)byte, 2, 16, QChar('0'));

参考

参考:
1、UDP广播与多播
2、Qt 网络编程-UDP
3、Qt中实现UDP的分包和组包——参考“草上爬”的博客

相关文章:

Qt——TCP UDP网络编程

目录 前言正文一、TCP二、UDP1、基本流程2、必备知识 三、代码层级1、UDP服务端 END、总结的知识与问题1、如何获取QByteArray中某一字节的数据&#xff0c;并将其转为十进制&#xff1f;2、如何以本年本月本日为基础&#xff0c;获取时间戳&#xff0c;而不以1970为基础&#…...

有什么安全处理方案可以有效防护恶意爬虫

常见的爬虫 有百度爬虫、谷歌爬虫、必应爬虫等搜索引擎类爬虫&#xff0c;此类爬虫经常被企业用于提高站点在搜索引擎内的自然排名&#xff0c;使得站点在各大搜索引擎中的排名能够提高&#xff0c;进一步通过搜索引擎来进行引流为企业增加业务流量。 恶意爬虫与合法、合规的搜…...

Flutter3.X基础入门教程(2024完整版)

Flutter介绍&#xff1a; Flutter是谷歌公司开发的一款开源、免费的UI框架&#xff0c;可以让我们快速的在Android和iOS上构建高质量App。它最大的特点就是跨平台、以及高性能。 目前Flutter已经支持 iOS、Android、Web、Windows、macOS、Linux的跨平台开发。 教程所讲内容支持…...

GEE——土地利用分类种两个矢量集合中不同列进行相减的方式(利用join进行连接处理)

问题: 我有两个具有相同 ID 的特征集,我想从第二个特征集中减去第一个特征集的表格单元格。 我使用了这个函数,但它计算的是表 1 中第一个元素与表 2 中其他元素的减法。 我想逐个单元格计算减法。第一个表格中 id 为 1 的单元格减去第二个表格中 id 为 1 的单元格,2x2、…...

mnn-llm: 大语言模型端侧CPU推理优化

在大语言模型(LLM)端侧部署上&#xff0c;基于 MNN 实现的 mnn-llm 项目已经展现出业界领先的性能&#xff0c;特别是在 ARM 架构的 CPU 上。目前利用 mnn-llm 的推理能力&#xff0c;qwen-1.8b在mnn-llm的驱动下能够在移动端达到端侧实时会话的能力&#xff0c;能够在较低内存…...

Freemarker实现Html全站静态化

全站静态化 在大型网站中&#xff0c;比如主流电商商品页&#xff0c;访问者看到的页面基本上是静态页面。为什么都要把页面静态化呢&#xff1f;其实把页面静态化&#xff0c;好处有很多。例如&#xff1a;访问速度快&#xff0c;更有利于搜索引擎收录等。 目前主流的静态化…...

16.顺子日期(14)

题目 public class Main {public static boolean isLegal(String date) {int l 0;int n date.length();while(l<(n-3)) {int t1 (int)Integer.valueOf(date.substring(l,l1));int t2 (int)Integer.valueOf(date.substring(l1,l2));int t3 (int)Integer.valueOf(date.s…...

《动手学深度学习》学习笔记 第5章 深度学习计算

本系列为《动手学深度学习》学习笔记 书籍链接&#xff1a;动手学深度学习 笔记是从第四章开始&#xff0c;前面三章为基础知道&#xff0c;有需要的可以自己去看看 关于本系列笔记&#xff1a; 书里为了让读者更好的理解&#xff0c;有大篇幅的描述性的文字&#xff0c;内容很…...

【Redis】非关系型数据库之Redis的介绍及安装配置

目录 前言 一、关系型数据库与非关系型数据库 1.1关系型数据库 1.2非关系型数据库 1.3两者的区别 1.4非关系型数据库产生的背景 1.5总结 二、Redis介绍 2.1Redis是什么 2.2Redis的优点 2.3Redis的使用场景 2.4那些数据适合放在缓存中 2.5Redis为什么那么快&#xf…...

3D模型轻量化

在线工具推荐&#xff1a;3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 近来&#xff0c;基于3D模型在影视作品、数字旅游项目诸多3D视觉领域都取得…...

数据分析——快递电商

一、任务目标 1、任务 总体目的——对账 本项目解决同时使用多个快递发货&#xff0c;部分隔离区域出现不同程度涨价等情形下&#xff0c;如何快速准确核对账单的问题。 1、在订单表中新增一列【运费差异核对】来表示订单运费实际有多少差异&#xff0c;结果为数值。 2、将…...

《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(8)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置&#xff08;7&#xff09; 2.2 HOST主桥 MPC8548处理器的拓扑结构如图2-2所示&#xff1a; 2.2.2 存储器域地址空间到PCI总线域地址空间的转换 MPC8548处理器使用ATMU&#xff…...

Hadoop分布式文件系统(二)

目录 一、Hadoop 1、文件系统 1.1、文件系统定义 1.2、传统常见的文件系统 1.3、文件系统中的重要概念 1.4、海量数据存储遇到的问题 1.5、分布式存储系统的核心属性及功能含义 2、HDFS 2.1、HDFS简介 2.2、HDFS设计目标 2.3、HDFS应用场景 2.4、HDFS重要特性 2.4…...

macOS跨进程通信: FIFO(有名管道) 创建实例

一&#xff1a; 简介 在类linux系统中管道分为有名管道和匿名管道。两者都能单方向的跨进程通信。 匿名管道&#xff08;pipe&#xff09;: 必须是父子进程之间&#xff0c;而且子进程只能由父进程fork() 出来的&#xff0c;才能继承父进程的管道句柄&#xff0c;一般mac 开发…...

推荐几个免费的HTTP接口Mock网站和工具

在前后端分离开发架构下&#xff0c;经常遇到调用后端数据API接口进行测试、集成、联调等需求&#xff0c;比如&#xff1a; &#xff08;1&#xff09;前端开发人员很快开发完成了UI界面&#xff0c;但后端开发人员的API接口还没有完成&#xff0c;不能进行前后端数据接口对接…...

企业数据库安全管理规范

1.目的 为规范数据库系统安全使用活动&#xff0c;降低因使用不当而带来的安全风险&#xff0c;保障数据库系统及相关应用系统的安全&#xff0c;特制定本数据库安全管理规范。 2.适用范围 本规范中所定义的数据管理内容&#xff0c;特指存放在信息系统数据库中的数据。 本…...

react:ffcreator中FFCreatorCenter视频队例

最近项目要求&#xff0c;一键生成房子的推荐视频&#xff0c;选几张图&#xff0c;加上联系人的方式就是一个简单的视频&#xff0c;因为有web端、小程序端&#xff0c;为了多端口用&#xff0c;决定放在服务器端生成。 目前用的是react中的nextjs来开发项目。 nextjs中怎样…...

力扣(leetcode)第434题字符串中的单词数(Python)

434.字符串中的单词数 题目链接&#xff1a;434.字符串中的单词数 统计字符串中的单词个数&#xff0c;这里的单词指的是连续的不是空格的字符。 请注意&#xff0c;你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: “Hello, my name is John” 输出: 5 解释: 这…...

django学习:页面渲染与请求和响应

1.请求过程 2.页面渲染 在app中新建一个目录&#xff08;Directory&#xff09;&#xff0c;文件名命名为templates。该文件名命名是固定的&#xff0c;不可命名出错&#xff0c;如若后续步骤出错&#xff0c;该目录文件名是一个检查的重点项目。在该目录下新建一个html文件&a…...

Redis 数据一致性

概述 当我们在使用缓存时&#xff0c;如果发生数据变更&#xff0c;那么你需要同时操作缓存和数据库&#xff0c;而它们两个又分属不同的系统&#xff0c;因此无法做到同时操作成功或失败&#xff0c;因此在并发读写下很可能出现缓存与数据库数据不一致的情况 理论上可以通过…...

Mac环境下反编译apk

Mac环境下反编译apk 安装反编译工具dex2jar&#xff1a;[官网下载](https://sourceforge.net/projects/dex2jar/)JD-GUI&#xff1a;[官网下载](https://jd-gui.apponic.com/) 实操1. 将需要反编译的 .apk 文件放在下载的 dex2jar 文件夹目录下2. 使用 cd /xxx/dex2jar-2.0 命令…...

计算机网络——网络模型的组织、看法以及标准化流程

1. 通信技术和标准化领域中扮演重要角色的组织 1.1 国际和国家官方标准化机构 OSI&#xff1a;国际标准化组织&#xff08;ISO&#xff09;&#xff0c;负责国际标准的制定&#xff0c;旨在确保全球产品和服务的安全性、可靠性和效率。它有许多国家分支机构&#xff0c;包括法…...

【JAVA】volatile 关键字的作用

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 volatile 的作用&#xff1a; 结语 我的其他博客 前言 在多线程编程中&#xff0c;保障数据的一致性和线程之间的可见性是…...

Next.js 第一次接触

因为需要整个漂亮的在线文档&#xff0c;所以接触了next.js&#xff0c;因为对前端js本身不够熟悉&#xff0c;别说对react.js 又不会&#xff0c;时间又不允许深入研究&#xff0c;所以&#xff0c;为了加一个导航菜单&#xff0c;极其痛苦。 有点小bug&#xff0c;不过不影响…...

CISSP 第7章:PKI和密码学应用

第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统&#xff0c;从而产生了安全秘钥分发的问题 非对称密码学使用公钥和私钥对&#xff0c;无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA&#xff08;兼具加密和数字签名&#xff09; RSA算法依赖…...

dji uav建图导航系列()ROS中创建dji_sdk节点包(二)实现代码

在前文 【dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构】中简单介绍了项目的结构,和一些配置文件的代码。本文详细说明目录src下的节点源代码实现。 文章目录 1、代码结构2、PSDK部分3、ROS部分3.1、头文件3.1.1、外部调用 node_service.h3.1.2、节点类定义…...

数字化工厂产品推荐 带OPC UA的分布式IO模块

背景 近年来&#xff0c;为了提升在全球范围内的竞争力&#xff0c;制造企业希望自己工厂的机器之间协同性更强&#xff0c;自动化设备采集到的数据能够发挥更大的价值&#xff0c;越来越多的传统型工业制造企业开始加入数字化工厂建设的行列&#xff0c;实现智能制造。 数字化…...

使用OHOS SDK构建opus

参照OHOS IDE和SDK的安装方法配置好开发环境。 从github下载源码。 执行如下命令&#xff1a; git clone --depth1 https://github.com/xiph/opus进入源码所在的目录&#xff0c;创建批处理文件ohos_build.cmd&#xff0c;内容如下&#xff1a; echo off setlocalset OHOS_…...

K-means 聚类算法分析

算法简述 K-means 算法原理 我们假定给定数据样本 X &#xff0c;包含了 n 个对象 &#xff0c;其中每一个对象都具有 m 个维度的属性。而 K-means 算法的目标就是将 n 个对象依据对象间的相似性聚集到指定的 k 个类簇中&#xff0c;每个对象属于且仅属于一个其到类簇中心距离…...

uniapp获取定位

Uniapp 是一种跨平台应用开发框架&#xff0c;它能够快速地构建出针对不同平台的应用程序。在Uniapp中&#xff0c;实现定位功能也变得十分简单&#xff0c;只需要简单的配置就能轻松实现。 一、高德地图根据指定位置获取经纬度 参考地址&#xff1a;地理/逆地理编码-基础 API…...

产品推广方案有哪些/金华百度seo

在开发项目时&#xff0c;对EditText 做了OnKey事件的监听 &#xff0c;但总是会触发两次&#xff01; 后来查阅很多资料后发现&#xff0c;Key有Down和Up事件&#xff0c;所以会执行两次。 解决方法&#xff1a;捕获UP 或DWON的其中一种 etTMH.setOnKeyListener(new OnKey…...

校园网站建设工作总结/网站模板怎么建站

问题重述 根据输入构造二叉树&#xff0c;输出该二叉树的先序序列。二叉树共有N个节点&#xff0c;节点编号是1到N。约定1号节点是根节点。 输入格式: 第一行输入整数N。 接下来有N行&#xff0c;依次给出1到N节点的左孩子和右孩子。对于这N行中的每一行&#xff0c;有两个整…...

国外做内容网站/专业网页设计和网站制作公司

ENVI和ArcGIS一体化集成技术使得遥感和GIS实现了一体化的应用。对于一些初学者来说利用Python脚本将ENVI/IDL编写的图像处理功能集成到ArcGIS中&#xff0c;进行一体化的数据处理和分析时可能会遇到一些问题&#xff0c;因为涉及到两种语言(IDL和python)的混合编程。混合编程成…...

网站域名可以做端口映射吗/seo入门

1 inverse&#xff0c;在一对多中使用&#xff0c;表示是否有关联关系控制权。对于保存、删除数据有影响。 2 cascade&#xff0c;表示级联操作 save-update 表示级联保存和更新 delete 表示级联删除 all 表示级联保存、更新、删除 3 一级缓存&#xff0c;session缓存又称一级缓…...

没有网站如何做天天联盟/软件开发外包公司

为什么80%的码农都做不了架构师&#xff1f;>>> 作为他的忠实粉丝&#xff0c;决定从今天开始&#xff0c;看到他的每一句经典的、有价值的、令人回味深长的话&#xff0c;都记录下来&#xff0c;以便反复学习。 问&#xff1a;学习设计模式有什么好书推荐&#x…...

乡镇政府可以做网站认/怎么推广自己的微信

2019独角兽企业重金招聘Python工程师标准>>> 仔细解剖web服务器的来龙去脉&#xff0c;以及前世今生&#xff1b; 一&#xff0c;计算机历史了解 第一代之前源于计算公式做物理计算机运算复杂公式&#xff08;计算机雏形&#xff09;&#xff1b; 第一代计算电子管计…...