python之网络编程

网络编程

互联网时代,现在基本上所有的程序都是网络程序,很少有单机版
的程序了。

网络编程就是如何在程序中实现两台计算机的通信。

Python语言中,提供了大量的内置模块和第三方模块用于支持各种
网络访问,而且Python语言在网络通信方面的优点特别突出,远远
领先其他语言。

通过本章可以学到

  • 了解TCP和UDP
  • 掌握编写UDP Socket客服端应用
  • 掌握编写UDP Socket服务端应用
  • 掌握编写TCP Socket客户端应用
  • 掌握编写TCP Socket服务端应用

基本概念

IP地址

IP是Internet Protocol Address,即"互联网协议地址"。

用来标识网络中的一个通信实体的地址。通信实体可以是计算机、路由器等。 比如互联网的每个服务器都要有自己的IP地址,而每个局域网的计算机要通信也要配置IP地址。

路由器是连接两个或多个网络的网络设备。

IP地址就像是我们的家庭住址一样,如果你要写信给一个人,你就要知道他(她)的地址,这样邮递员才能把信送到。计算机发送信息就好比是邮递员,它必须知道唯一的“家庭地址”才能不至于把信送错人家。只不过我们的地址是用文字来表示的,计算机的地址用二进制数字表示。IP地址被用来给Internet上的电脑一个编号。大家日常见到的情况是每台联网的PC上都需要有IP地址,才能正常通信。我们可以把“个人电脑”比作“一台电话”,那么“IP地址”就相当于“电话号码”,而Internet中的路由器,就相当于电信局的“程控式交换机”。

类别最大网络数IP地址范围 单个网段最大
主机数 
私有IP地址范围
A126(2^7-2)1.0.0.1-
127.255.255.254 
1677721410.0.0.0-
10.255.255.255
B16384(2^14)128.0.0.1-
191.255.255.254 
65534 172.16.0.0-
172.31.255.255
2097152(2^21) 192.0.0.1-
223.255.255.254
254192.168.0.0-
192.168.255.255

至于为什么最大网络数要减去2,这个就是计算机网络的知识了。

目前主流使用的IP地址是IPV4,但是随着网络规模的不断扩大,
IPV4面临着枯竭的危险,所以推出了IPV6。

IPV4,采用32位地址长度,只有大约43亿个地址,它只有4段
数字,每一段最大不超过255。随着互联网的发展,IP地址不够
用了,在2019年11月25日IPv4位地址分配完毕。

IPv6采用128位地址长度,几乎可以不受限制地提供地址。按保
守方法估算IPv6实际可分配的地址,整个地球的每平方米面积
上仍可分配1000多个地址。

IP地址实际上是一个32位整数(称为IPv4),以字符串表示的IP地址如 192.168.0.1 实际上是把32位整数按8位分组后的数字表示,目的是便于阅读。

IPv6地址实际上是一个128位整数,它是目前使用的IPv4的升级版,以字符串表示类似于 2001:0db8:85a3:0042:1000:8a2e:0370:73343

公有地址

公有地址(Public address)由Inter NIC(Internet NetworkInformation Center互联网信息中心)负责。这些IP地址分配给注册并向Inter NIC提出申请的组织机构。通过它直接访问互联网。

私有地址

私有地址(Private address)属于非注册地址,专门为组织机构内
部使用。

以下列出留用的内部私有地址
A类 10.0.0.0--10.255.255.255
B类 172.16.0.0--172.31.255.255
C类 192.168.0.0--192.168.255.255

注意事项

  • 127.0.0.1本机地址
  • 192.168.0.0-192.168.255.255为私有地址,属于非注册地址,专门为组织机构内部使用

实操:

  1. windows下,我们可以通过命令ipconfig获取网卡信息。Linux和Mac,是 ifconfig )
  2. 通过ping查看网络连接:
  • ping www.baidu.com 查看是否能上公网
  • ping 192.168.1.100 查看是否和该计算机在同一个局域网
  • ping 127.0.0.1 查看本机网卡是否可用

端口port

端口号用来识别计算机中进行通信的应用程序。因此,它也被称为程序地址。

一台计算机上同时可以运行多个程序。传输层协议正是利用这些端口号识别本机中正在进行通信的应用程序,并准确地进行数据传输。

总结

  • IP地址好比每个人的地址(门牌号),端口好比是房间号。必须同时指定IP地址和端口号才能够正确的发送数据。
  • IP地址好比为电话号码,而端口号就好比为分机号。

端口分配

端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。 端口的表示是一个16位的二进制整数,对应十进制的0-65535。

操作系统中一共提供了0~65535可用端口范围。

按端口号分类:

公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。

注册端口(Registered Ports):从1024到65535。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。

网络通信协议

国际标准化组织(ISO,即International Organization forStandardization)定义了网络通信协议的基本框架,被称为OSI(Open System Interconnect,即开放系统互联)模型。要制定通讯规则,内容会很多,比如要考虑A电脑如何找到B电脑,A电脑在发送信息给B电脑时是否需要B电脑进行反馈,A电脑传送给B电脑的数据格式又是怎样的?内容太多太杂,所以OSI模型将这些通讯标准进行层次划分,每一层次解决一个类别的问题,这样就使得标准的制定没那么复杂。OSI模型制定的七层标准模型,分别是:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。

OSI七层协议模型如图所示:

网络协议的分层

虽然国际标准化组织制定了这样一个网络通信协议的模型,但是实际上互联网通讯使用最多的网络通信协议是TCP/IP网络通信协议。

TCP/IP 是一个协议族,也是按照层次划分,共四层:应用层,传输
层,网络层,网络接口层(物理+数据链路层)。

把用户应用程序作为最高层,把物理通信线路作为最低层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。

ISO模型与TCP/IP模型的对应关系如图所示。

TCP和UDP协议区别

TCP 和 UDP 的优缺点无法简单地、绝对地去做比较:TCP 用于在传输层有必要实现可靠传输的情况;UDP 主要用于那些对高速传输和实时性有较高要求的通信或广播通信。TCP 和 UDP 应该根据应用的目的按需使用。

TCP

TCP(Transmission Control Protocol,传输控制协议)。TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。

UDP

UDP(User Data Protocol,用户数据报协议)
UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。 在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、 计算机的能力和传输带宽的限制; 在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。

UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP

TCP和UDP区别

这两种传输方式都在实际的网络编程中使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则可以通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据传递。

由于TCP需要建立专用的虚拟连接以及确认传输是否正确,所以使用TCP方式的速度稍微慢一些,而且传输时产生的数据量要比UDP稍微大一些。

UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数支持一对一,一多,多对一和多对多交互通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
适用场景适用于实时应用(IP电话、视频会议、直播等)适用于要求可靠传输的应用,例如文
件传输

总结

  • TCP是面向连接的,传输数据安全,稳定,效率相对较低。
  • UDP是面向无连接的,传输数据不安全,效率较高。

TCP建立连接的三次握手

TCP是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。 一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂, 只简单的描述下这三次对话的简单过
程:

1)主机A向主机B发出连接请求:“我想给你发数据,可以吗?”,这
是第一次对话;
2)主机B向主机A发送同意连接和要求同步 (同步就是两台主机一
个在发送,一个在接收,协调工作)的数据包 :“可以,你什么时候
发?”,这是第二次对话;
3)主机A再发出一个数据包确认主机B的要求同步:“我现在就发,
你接着吧!”, 这是第三次握手。

三次“对话”的目的是使数据包的发送和接收同步, 经过三次“对话”
之后,主机A才向主机B正式发送数据。

  1. 第一步,客户端发送一个包含SYN即同步(Synchronize)标志的TCP报文,SYN同步报文会指明客户端使用的端口以及TCP连接的初始序号。
  2. 第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)
  3. 第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。然后才开始通信的第二步:数据处理。

这就是所说的TCP的三次握手(Three-way Handshake)

为什么TCP协议有三次握手,而UDP协议没有?
因为三次握手的目的是在client端和server端建立可靠的连接。保证双方发送的数据对方都能接受到,这也是TCP协议的被称为可靠的数据传输协议的原因。而UDP就不一样,UDP不提
供可靠的传输模式,发送端并不需要得到接收端的状态,因此UDP协议就用不着使用三次握手。

TCP断开连接的四次挥手

TCP建立连接要进行3次握手,而断开连接要进行4次:

第一次: 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP
连接的请求 ;
第二次: 主机B收到FIN后对其作出响应,确认这一方向上的TCP连
接将关闭,将ACK置1;
第三次: 由B 端再提出反方向的关闭请求,将FIN置1 ;
第四次: 主机A对主机B的请求进行确认,将ACK置1,双方向的关
闭结束.。

由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式, 大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互, 为数据正式传输打下了可靠的基础。

数据包与处理流程

什么是数据包

通信传输中的数据单位,一般也称“数据包”。在数据包中包括:包、帧、数据包、段、消息。

网络中传输的数据包由两部分组成:一部分是协议所要用到的首部,另一部分是上一层传过来的数据。首部的结构由协议的具体规范详细定义。在数据包的首部,明确标明了协议应该如何读取据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。包首部就像协议的脸。

数据包处理流程

套接字编程实战

socket编程介绍

TCP协议和UDP协议是传输层的两种协议。Socket是传输层供给应用层的编程接口,所以Socket编程就分为TCP编程和UDP编程两类。

Socket编程封装了常见的TCP、UDP操作,可以实现非常方便的网络编程。

socket()函数介绍

在Python语言标准库中,通过使用socket模块提供的socket对象,可以在计算机网络中建立可以互相通信的服务器与客户端。在服务器端需要建立一个socket对象,并等待客户端的连接。客户端使用socket对象与服务器端进行连接,一旦连接成功,客户端和服务器端就可以进行通信了。

上图中,我们可以看出socket通讯中,发送和接收数据,都是通过操作系统控制网卡来进行。因此,我们在使用之后,必须关闭socket。

在Python 中,通常用一个Socket表示“打开了一个网络连接”,语法格式如下:

socket.socket([family[, type[, proto]]])

family : 套接字家族可以使 AF_UNIX 或者 AF_INET 

AF 表示ADDRESS FAMILY 地址族
AF_INET(又称 PF_INET)是 IPv4 网络协议的套接字类型;而
AF_UNIX 则是 Unix 系统本地通信。

type : 套接字类型可以根据是面向连接的还是非连接分为 SOCK_STREAM或 SOCK_DGRAM ; protocol : 一般不填,默认为0。

Socket主要分为面向连接的Socket和无连接的Socket。

无连接Socket的主要协议是用户数据报协议,也就是常说的UDP,UDP Socket的名字是 SOCK_DGRAM 。创建套接字UDP/IP套接字,可以调用 socket.socket() 。示例代码如下:

udpSocket=socket.socket (AF_INET,SOCK_DGRAM)

socket对象的内置函数和属性

在Python语言中socket对象中,提供如表所示的内置函数。

函数功能
服务器端套接字函数
s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen()开始TCP监听。backlog指定在拒绝连接之前,操作系统
可以挂起的最大连接数量。该值至少为1,大部分应用程
序设为5就可以了。
s.accept()被动接受TCP客户端连接,(阻塞式)等待连接的到来
客户端套接字
s.connect()主动初始化TCP服务器连接,。一般address的格式为元
组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出
异常
公共用途的套接字函数
s.recv()接收TCP数据,数据以字符串形式返回,bufsize指定要
接收的最大数据量。flag提供有关消息的其他信息,通常
可以忽略。
s.send()发送TCP数据,将string中的数据发送到连接的套接字。
返回值是要发送的字节数量,该数量可能小于string的字
节大小。
s.sendall()完整发送TCP数据,完整发送TCP数据。将string中的数
据发送到连接的套接字,但在返回之前会尝试发送所有
数据。成功返回None,失败则抛出异常。
s.recvfrom()接收UDP数据,与recv()类似,但返回值是
(data,address)。其中data是包含接收数据的字符
串,address是发送数据的套接字地址。
s.sendto()发送UDP数据,将数据发送到套接字,address是形式为
(ipaddr,port)的元组,指定远程地址。返回值是发
送的字节数。
s.close()关闭套接字
s.getpeername()返回连接套接字的远程地址。返回值通常是元组
(ipaddr,port)。
s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt(level,optname,value)设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen]) 返回套接字选项的值。
函数功能
s.settimeout(timeout)设置套接字操作的超时期,timeout是一个浮点数,单位
是秒。值为None表示没有超时期。一般,超时期应该在
刚创建套接字时设置,因为它们可能用于连接的操作
(如connect())
s.gettimeout()返回当前超时期的值,单位是秒,如果没有设置超时
期,则返回None。
s.fileno() 返回套接字的文件描述符。
s.setblocking(flag)如果flag为0,则将套接字设为非阻塞模式,否则将套接
字设为阻塞模式(默认值)。非阻塞模式下,如果调用
recv()没有发现任何数据,或send()调用无法立即发送数
据,那么将引起socket.error异常。
s.makefile()创建一个与该套接字相关连的文件

UDP编程介绍

UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要
求可靠到达的数据,就可以使用UDP协议。

创建Socket时, SOCK_DGRAM 指定了这个Socket的类型是UDP。绑定端口和TCP一样,但是不需要调用 listen() 方法,而是直接接收来自任何客户端的数据。 recvfrom() 方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用 sendto() 就可以把数据用UDP发给客户端。

UDP编程的实现

【示例】UDP接收数据

from socket import *s = socket(AF_INET, SOCK_DGRAM)  # 创建一个无连接的套接字
# 绑定接受信息端口
s.bind(('127.0.0.1', 8877))  # 绑定一个端口,ip地址和端口号
print("等待接收数据!")
redata = s.recvfrom(1024)  # 1024表示本次接收的最大字节数,redata返回的数据为消#息和地址
print(redata)
print(f'收到远程信息:{redata[0].decode("gbk")},from{redata[1]}')
s.close()

【示例】UDP发送数据

from socket import *s = socket(AF_INET, SOCK_DGRAM)  # 创建套接字
addr = ('127.0.0.1', 8877)  # 准备接收方地址
data = input("请输入:")
# 发送数据时,python3需要将字符串转成byte
s.sendto(data.encode('gbk'), addr)  # 默认的网络助手使用的编码是gbk,sendto的第一个参数为要发送的数据,第二个参数为要发送参数的地址
s.close()

注意!!!

不是专业版的pycharm不能同时开两个程序,可以打开一个pycharm后再打开一个pycharm。

持续通信

【示例】UDP接受数据

from socket import *s = socket(AF_INET, SOCK_DGRAM)  # 创建UDP类型的套接字
s.bind(("127.0.0.1", 8877))  # 绑定端口,ip可以不写
print("等待接收数据!")
while True:recv_data = s.recvfrom(1024)  # 1024表示本次接收的最大字节数recv_content = recv_data[0].decode('gbk')print(f"收到远程信息:{recv_content},from{recv_data[1]}")if recv_content == "88":print("结束聊天!")break
s.close()

【示例】UDP发送数据

# -*- coding: utf-8 -*-
from socket import *s = socket(AF_INET, SOCK_DGRAM)  # 创建UDP类型的套接字
addr = ("127.0.0.1", 8877)
while True:data = input("请输入:")s.sendto(data.encode("gbk"), addr)if data == "88":print("结束聊天!")break
s.close()

结合多线程实现UDP双向自由通信

UDP 不同于 TCP,不存在请求连接和受理过程,因此在某种意义上无法明确区分服务器端和客户端,只是因为其提供服务而称为服务器端。

如下服务端、客户端代码几乎一模一样,注意接收和发送端口对应,即可

【示例】UDP实现多线程服务端

# -*- coding: utf-8 -*-
from socket import *
from threading import Threadudp_socket = socket(AF_INET, SOCK_DGRAM)
udp_socket.bind(("127.0.0.1", 8989))# 不停的接收
def recv_data():while True:redata = udp_socket.recvfrom(1024)print(f'收到消息:{redata[0].decode("gbk")},from{redata[1]}')def send_data():while True:data = input('输入信息:')addr = ('127.0.0.1', 8080)udp_socket.sendto(data.encode('gbk'), addr)if __name__ == '__main__':# 创建两个线程t1 = Thread(target=send_data)t2 = Thread(target=recv_data)t1.start()t2.start()t1.join()t2.join()

【示例】UDP实现多线程客户端

# -*- coding: utf-8 -*-
from socket import *
from threading import Threadudp_socket = socket(AF_INET, SOCK_DGRAM)
udp_socket.bind(("127.0.0.1", 8989))# 不停的接收
def recv_data():while True:redata = udp_socket.recvfrom(1024)print(f'收到消息:{redata[0].decode("gbk")},from{redata[1]}')def send_data():while True:data = input('输入信息:')addr = ('127.0.0.1', 8080)udp_socket.sendto(data.encode('gbk'), addr)if __name__ == '__main__':# 创建两个线程t1 = Thread(target=send_data)t2 = Thread(target=recv_data)t1.start()t2.start()t1.join()t2.join()

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

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

相关文章

@Autowired 和 @Resource 注解的区别

前言 Autowired 和 Resource 是 Spring 中用于依赖注入的注解,但两者在实现机制和使用方式上有显著差异。 主要区别 1.来源不同 Autowired:由 Spring 框架提供(org.springframework.beans.factory.annotation),与 S…

2024年数维杯数学建模B题生物质和煤共热解问题的研究解题全过程论文及程序

2024年数维杯数学建模 B题 生物质和煤共热解问题的研究 原题再现: 随着全球能源需求的不断增长和对可再生能源的追求,生物质和煤共热解作为一种潜在的能源转化技术备受关注。生物质是指可再生能源,源自植物和动物的有机物质,而煤…

计算机网络——物理层设备

目录 ​编辑 中继器 集线器(Hub) 集线器,中继器的一些特性 集线器和中继器不能“无限串联” 集线器连接的网络,物理上是星型拓扑,逻辑上是总线型拓扑 集线器连接的各网段会“共享带宽” 中继器 如果我们想要网络…

NVIDIA NeMo 全面教程:从入门到精通

NVIDIA NeMo 全面教程:从入门到精通 文章目录 NVIDIA NeMo 全面教程:从入门到精通目录框架介绍NeMo的核心特点NeMo的架构NeMo与其他框架的比较NeMo的模型集合NeMo的工作流程NeMo 2.0的新特性 安装指南系统要求使用Docker容器安装步骤1:安装Do…

Chrome 134 版本开发者工具(DevTools)更新内容

Chrome 134 版本开发者工具(DevTools)更新内容 一、隐私与安全面板 旧的 Security 面板已演变为隐私与安全面板,并新增了一个专注于隐私的部分。在该部分中,可以: 在 DevTools 打开时,临时限制第三方 Co…

顺序表和链表

目录 线性表顺序表概念与结构分类静态顺序表动态顺序表 动态顺序表的实现SeqList.hSeqLIst.c 和 test.c初始化SLInit增容SLCheckCapacity尾插SLPushBack打印SLPrint头插SLPushFront尾删SLPopBack头删SLPopFront查找SLFind任意插SLInsert任意删SLErase销毁顺序表SLDestroy 顺序表…

性能测试、负载测试、压力测试的全面解析

在软件测试领域,性能测试、负载测试和压力测试是评估系统稳定性和可靠性的关键手段。​它们各自关注不同的测试目标和应用场景,理解这些差异对于制定有效的测试策略至关重要。 本文对性能测试、负载测试和压力测试进行深入分析,探讨其定义、…

FPGA_YOLO(二)

上述对cnn卷积神经网络进行介绍,接下来对YOLO进行总结,并研究下怎么在FPGA怎么实现的方案。 对于一个7*7*30的输出 拥有49个cell 每一个cell都有两个bbox两个框,并且两个框所包含的信息拥有30个 4个坐标信息和一个置信度5个,剩下就是20个类别。 FPGA关于YOLO的部署 1…

Windows系统安装Node.js和npm教程【成功】

0.引言——Node.js和npm介绍 项目描述Node.js基于Chrome V8引擎的JavaScript运行环境,使JavaScript可用于服务器端开发。采用单线程、非阻塞I/O及事件驱动架构,适用于构建Web服务器、实时应用和命令行工具等npmNode.js的包管理器与大型软件注册表。拥有…

使用外部事件检测接入 CDH 大数据管理平台告警

CDH 大数据管理平台 CDH(Cloudera Distribution Hadoop)是一个企业级的大数据平台,由 Cloudera 公司提供,它包含了 Apache Hadoop 生态系统中的多种开源组件,并对其进行了优化和集成,以支持大规模数据存储…

Node.js的安装和环境配置

漂亮女同事想了解Node.js的安装和环境配置。首先,我说需要回忆一下自己安装Node.js的经历,确保步骤是正确的。可能用户是刚接触开发的新手,所以需要详细但清晰的指导。 首先,应该介绍Node.js是什么,不过用户可能已经知…

在普通用户下修改root用户密码

1 从普通用户切换到root用户 sudo -s 再输入密码。 2 输入passwd ,会提醒你输入当前用户密码,验证后会提醒你输入root用户密码。 3 切换到root用户,使用修改过的密码登陆。 4 成功进入root用户。

【#2】介绍第三方库

一、JsonCpp 库 🔥 JSONCPP 是一个开源的 C 库,用于解析和生成 JSON(JavaScript Object Notation)数据。它提供了简单易用的接口,支持 JSON 的序列化和反序列化操作,适用于处理配置文件、网络通信数据等场…

Qt开发:QInputDialog的使用

文章目录 一、QInputDialog的介绍二、 QInputDialog的基本用法三、使用 QInputDialog的实例四、QInputDialog的信号与槽 一、QInputDialog的介绍 QInputDialog 是 Qt 提供的一个对话框类,用于获取用户输入的文本、整数或浮点数。它提供了简单易用的静态方法和可定制…

SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测

SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测 目录 SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.【SCI一区级】Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测(程…

Vulnhub-Thales通关攻略

第0步:网卡配置 靶机端:将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式 Kali端:将 VMware 中桥接模式网卡设置为 VritualBox 的 Host-only 第一步:确定靶机IP #靶机IP 192.168.56.101#KaliIP 1…

JVM 02

今天是2025/03/23 19:07 day 10 总路线请移步主页Java大纲相关文章 今天进行JVM 3,4 个模块的归纳 首先是JVM的相关内容概括的思维导图 3. 类加载机制 加载过程 加载(Loading) 通过类全限定名获取类的二进制字节流(如从JAR包、网络、动态…

Python学习笔记(7)关于列表创建,增加,删除

列表 **Python中一切都是对象 存放多个值的连续内存空间 大小可变 增加元素 a a[50]#➕运算符操作,产生了新对象 list.append(x) #将元素x增加至list尾部 list.extend(alist) #将列表alist增加至list尾部 list.insert(index.x) #将元素x插入list指定index位置 …

【图片识别Excel表格】批量将图片上的区域文字识别后保存为表格,基于WPF和阿里云的项目实战总结

一、项目背景 在信息处理和文档管理中,经常会遇到需要从大量图片中提取文字并进行整理的场景。例如,财务部门需要从大量报销票据中提取金额、日期等信息;法务部门需要从合同文档中提取关键条款;教育行业需要从试卷中提取学生的答题内容等。传统的手工处理方式不仅耗时长、…

【C语言】文件操作(详解)

个人主页 今天我们来讲一下有关文件的相关操作,希望看完这篇文章对你有所帮助,大力感谢你对博主的支持! 文章目录 ⭐一、为什么使用文件🎉二、什么是文件2.1 程序文件2.2 数据文件2.3 文件名 🎡三、二进制文件和文本…