pt13网络编程
网络编程
-  OSI 7层模型 -  建立了统一的通信标准 
-  降低开发难度,每层功能明确,各司其职 
-  七层模型实际规定了每一层的任务,该完成什么事情 
 
-  
-  TCP/IP模型 - 七层模型过于理想,结构细节太复杂
- 在工程中应用实践难度大
- 实际工作中以TCP/IP模型为工作标准流程
 
-  网络协议 -  什么是网络协议:在网络数据传输中,都遵循的执行规则。 
-  网络协议实际上规定了每一层在完成自己的任务时应该遵循什么规范。 
 
-  
-  需要应用工程师做的工作 : 编写应用工功能,明确对方地址,选择传输服务。 
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cuMqe1Y4-1682691580328)(picture\2317130415.jpg)]
UDP 传输方法
UDP套接字编程
套接字(Socket) : 实现网络编程进行数据传输的一种技术手段,网络上各种各样的网络服务大多都是基于 Socket 来完成通信的。
创建套接字
import  socketsock=socket.socket(family,type)功能:创建套接字参数:family  网络地址类型 AF_INET表示ipv4,默认值type  套接字类型 SOCK_DGRAM 表示udp套接字 默认是tcp(也叫数据报套接字) 返回值: 套接字对象
绑定地址
sock.bind(addr)功能: 绑定本机网络地址参数: 二元元组 (ip,port)  ('0.0.0.0',8888)   自动获取地址0.0.0.0
"""
套接字选择
"""
import socket# 创建UDP套接字
udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 绑定一个IP地址和端口
udp_socket.bind(("0.0.0.0", 8888))# 创建TCP套接字
# tcp_socket=socket.socket(socket.AF_INET,
#                          socket.SOCK_STREAM)
消息收发
data,addr = sock.recvfrom(buffersize)功能: 接收UDP消息参数: 每次最多接收多少字节返回值: data  接收到的内容addr  消息发送方地址n = sock.sendto(data,addr)功能: 发送UDP消息参数: data  发送的内容 bytes格式addr  目标地址返回值:发送的字节数
关闭套接字
sock.close()功能:关闭套接字
练习
"""
udp服务端实例代码  重点代码 !!!
"""
from socket import *# 创建UDP套接字
udp_socket = socket(AF_INET,SOCK_DGRAM)#  绑定地址
udp_socket.bind(("0.0.0.0",8888))while True:# 接收发送消息  data--> bytesdata,addr = udp_socket.recvfrom(5)# if data == b"##":#     breakprint("从",addr,"收到:",data.decode())# 发送给刚才收到的地址udp_socket.sendto(b"Thanks",addr)# 关闭套接字
udp_socket.close()#######################################################"""
udp 客户端示例    重点代码!!
"""
from socket import *# 服务器地址
ADDR = ("127.0.0.1",8888)# 与服务端相同套接字
udp_socket = socket(AF_INET,SOCK_DGRAM)# 发送消息
while True:msg = input(">>")if not msg:breakudp_socket.sendto(msg.encode(),ADDR)# 结束发送# if msg == "##":#     breakdata,addr = udp_socket.recvfrom(128)print("从服务端收到:",data.decode())udp_socket.close()
随堂练习:使用udp完成网络单词查询,从客户端输入单词,发送给服务端,得到单词的解释,打印出来
利用 dict 数据库下的 words表来完成
########################## 服务端 ###############################
from socket import *
import pymysql# 数据处理类
class Dict:def __init__(self):self.kwargs = {"host": "localhost","port": 3306,"user": "root","password": "123456","database": "dict","charset": "utf8"}self.connect()# 完成数据库连接def connect(self):self.db = pymysql.connect(**self.kwargs)self.cur = self.db.cursor()# 关闭def close(self):self.cur.close()self.db.close()def get_mean(self, word):sql = "select mean from words where word=%s;"self.cur.execute(sql, [word])mean = self.cur.fetchone()  # (mean,) Noneif mean:return mean[0]else:return "Not Found"# 逻辑处理 网络搭建
class QueryWord:def __init__(self, host="0.0.0.0", port=8888):self.host = hostself.port = portself.dict = Dict()self.sock = self.create_socket()def create_socket(self):sock = socket(AF_INET, SOCK_DGRAM)sock.bind((self.host, self.port))return sockdef close(self):self.sock.close()# 查找单词方法def query_word(self):while True:word, addr = self.sock.recvfrom(128)# 查询单词mean = self.dict.get_mean(word.decode())self.sock.sendto(mean.encode(), addr)if __name__ == '__main__':query = QueryWord()query.query_word()############################ 客户端代码#########################
from socket import *# 服务器地址
ADDR = ("127.0.0.1",8888)class QueryWord:def __init__(self):self.sock = socket(type=SOCK_DGRAM)def close(self):self.sock.close()# 网络传输def recv_mean(self,word):self.sock.sendto(word.encode(),ADDR)mean,addr = self.sock.recvfrom(1024)return mean.decode()# 输入输出def query_word(self):while True:word = input("Word:")if not word:breakmean = self.recv_mean(word)print("%s : %s"%(word,mean))if __name__ == '__main__':query = QueryWord()query.query_word() # 查单词query.close()
UDP套接字特点
可能会出现数据丢失的情况、 传输过程简单,实现容易
数据以数据包形式表达传输、 数据传输效率较高
TCP 传输方法
TCP传输特点
面向连接的传输服务,数据传输过程中无丢失,无失序,无差错,无重复。三次握手四次挥手。
TCP服务端
创建套接字
sock=socket.socket(family,type)功能:创建套接字参数:family  网络地址类型 AF_INET表示ipv4type  套接字类型 SOCK_STREAM 表示tcp套接字 (也叫流式套接字) 返回值: 套接字对象
绑定地址
sock.bind(addr)功能: 绑定本机网络地址参数: 二元元组 (ip,port)  ('0.0.0.0',8888)   自动获取地址0.0.0.0
设置监听
sock.listen(n)功能 : 将套接字设置为监听套接字,确定监听队列大小参数 : 监听队列大小
处理客户端连接请求
conn,addr = sock.accept()功能: 阻塞等待处理客户端请求返回值: conn  客户端连接套接字addr  连接的客户端地址
消息收发
data = conn.recv(buffersize)功能 : 接受客户端消息参数 :每次最多接收消息的大小返回值: 接收到的内容n = conn.send(data)功能 : 发送消息参数 :要发送的内容  bytes格式返回值: 发送的字节数
#不再像UDP一样,在这里返回地址了
关闭套接字
tcp_socket.close()
请求连接
sock.connect(server_addr)功能:连接服务器参数:元组  服务器地址
"""
tcp 服务端流程  重点代码 !!   长连接形态
"""
from socket import *# 创建tcp套接字
tcp_socket = socket(AF_INET, SOCK_STREAM)# 绑定地址
tcp_socket.bind(("0.0.0.0", 8888))# 设置监听
tcp_socket.listen(5)# 循环处理客户端连接
while True:print("等待连接....")conn, addr = tcp_socket.accept()print("连接:", addr)# 先收后发while True:data = conn.recv(1024)    #客户端退出,返回空# 两种结束情况 客户端退出返回空   客户端指令##if not data or data == b"##":breakprint("收到:", data.decode())conn.send(b"Thanks")conn.close()# 关闭套接字
tcp_socket.close()"""
tcp 客户端   重点代码 !!
"""
from socket import *# 服务器地址
ADDR = ("127.0.0.1", 8888)# 创建相同类型套接字
tcp_socket = socket()# 建立连接
tcp_socket.connect(ADDR)# 循环 发送 接收    注意: 防止两端都阻塞,recv send要配合
while True:msg = input(">>")tcp_socket.send(msg.encode())if msg == '##':break  # 结束循环data = tcp_socket.recv(1024)print(data.decode())tcp_socket.close()
短连接形态了解
"""
tcp 服务端流程  短连接形态
"""
from socket import *# 创建tcp套接字
tcp_socket = socket(AF_INET, SOCK_STREAM)# 绑定地址
tcp_socket.bind(("0.0.0.0", 8888))# 设置监听
tcp_socket.listen(5)# 循环处理客户端连接
while True:conn, addr = tcp_socket.accept()data = conn.recv(1024)print("收到:", data.decode())conn.send(b"Thanks")conn.close()# 关闭套接字
tcp_socket.close()############################################################
"""
tcp 客户端
"""
from socket import *# 服务器地址
ADDR = ("127.0.0.1", 8888)# 循环输入发送
while True:msg = input(">>")if not msg:breaktcp_socket = socket()  # 每次发消息都要重新 创建套接字tcp_socket.connect(ADDR)tcp_socket.send(msg.encode())data = tcp_socket.recv(1024)print(data.decode())tcp_socket.close()
练习
在客户端将一张图片上传到服务端,图片自选,上传到服务端后命名为 recv.jpg思路: 客户端   获取文件内容--》发送出去服务端   接收文件内容--》写入磁盘########################## 服务端部分 #####################
from  socket import *# 接收内容,写入文件
def recv_file(connfd):file = open("recv.jpg",'wb')# 边收边写while True:data = connfd.recv(1024)if data == b"##":breakfile.write(data)file.close()connfd.send("上传完毕".encode())#搭建网络模型
def main():# 创建tcp套接字tcp_socket = socket()tcp_socket.bind(("0.0.0.0",8888))tcp_socket.listen(5)while True:connfd,addr = tcp_socket.accept()print("Connect from",addr)# 接收文件recv_file(connfd)connfd.close()if __name__ == '__main__':main()############################ 客户端部分 ###################################from socket import *def send_file(tcp_socket,filename):file = open(filename,"rb")# 边读边发送while True:data = file.read(1024)if not data:breaktcp_socket.send(data)file.close()tcp_socket.send(b"##") # 告知服务端结束msg = tcp_socket.recv(128)print(msg.decode())def main(filename):tcp_socket = socket()tcp_socket.connect(("127.0.0.1",8888))# 发送文件send_file(tcp_socket,filename)tcp_socket.close()if __name__ == '__main__':main("./zly.jfif")
TCP服务端示例02:from socket import *# 创建tcp套接字
tcp_socket = socket(AF_INET,SOCK_STREAM)# 绑定地址
tcp_socket.bind(("0.0.0.0",8880))# 设置为监听套接字
tcp_socket.listen(5)# 循环连接 收发 断开 -》 每次发送消息都需要连接
while True:connfd,addr = tcp_socket.accept()data = connfd.recv(1024)print("收到:",data.decode())connfd.send(b"Thanks")connfd.close()# 关闭套接字
tcp_socket.close()
TCP客户端示例02:from socket import *# 服务端地址
ADDR = ("127.0.0.1",8880)# 循环发送接收消息
while True:msg = input(">>")if not msg:breaktcp_socket = socket()tcp_socket.connect(ADDR)tcp_socket.send(msg.encode())data = tcp_socket.recv(1024)print("From server:",data.decode())tcp_socket.close()
TCP套接字细节
-  tcp连接中当一端退出,另一端如果阻塞在recv,此时recv会立即返回一个空字串。 
-  tcp连接中如果一端已经不存在,仍然试图通过send向其发送数据则会产生BrokenPipeError 
-  一个服务端可以同时连接多个客户端,也能够重复被连接 
-  tcp粘包问题 -  产生原因 - 为了解决数据再传输过程中可能产生的速度不协调问题,操作系统设置了缓冲区
- 实际网络工作过程比较复杂,导致消息收发速度不一致
- tcp以字节流方式进行数据传输,在接收时不区分消息边界
 
-  带来的影响 - 如果每次发送内容是一个独立的含义,需要接收端独立解析此时粘包会有影响。
 
-  处理方法 - 消息格式化处理,如人为的添加消息边界,用作消息之间的分割
 
-  控制发送的速度 
 
-  
随堂练习:
在客户端有一些数据
data = ["张三  18   177","李四  19   180","王五  120  183"
]
从客户端向服务端发送这些数据,在服务端将这些数据分别写入到一个文件中,每个数据占一行
客户端发送完成是 向服务端发送 '#' 表示发送完毕######################### 服务端 ######################
from socket import *# 接收数据 (对应客户端方法1)
# def recv_data(connfd):
#     file = open("student.txt",'w')
#     while True:
#         data = connfd.recv(1024).decode()
#         if data == '##':
#             break
#         file.write(data + '\n')
#     file.close()# 接收数据 (对应客户端方法2)
def recv_data(connfd):file = open("student.txt", 'wb')# data--> xxxx\nxxxx\nxxxx\ndata = connfd.recv(1024 * 1024)file.write(data)file.close()def main():sock = socket()sock.bind(("0.0.0.0",8888))sock.listen(3)connfd,addr = sock.accept()print("连接:",addr)recv_data(connfd) # 接收数据if __name__ == '__main__':main()###################### 客户端  ################################from socket import *
from time import sleepdata = ["张三  18   177","李四  19   180","王五  120  183"
]# 发送数据  (处理粘包方法1)
# def send_data(sock):
#     for item in data:
#         sock.send(item.encode())
#         sleep(0.1) # 延迟发送
#     sock.send(b"##") #   表示发送完成# 发送数据  (处理粘包方法2)
def send_data(sock):info = '\n'.join(data)sock.send(info.encode()) # 一次性发送def main():sock = socket()sock.connect(("127.0.0.1",8888))send_data(sock) # 发送数据sock.close()if __name__ == '__main__':main()
TCP与UDP对比
-  传输特征 - TCP提供可靠的数据传输,但是UDP则不保证传输的可靠性
- TCP传输数据处理为字节流,而UDP处理为数据包形式
- TCP传输需要建立连接才能进行数据传,效率相对较低,UDP比较自由,无需连接,效率较高
 
-  套接字编程区别 - 创建的套接字类型不同
- tcp套接字会有粘包,udp套接字有消息边界不会粘包
- tcp套接字依赖listen accept建立连接才能收发消息,udp套接字则不需要
- tcp套接字使用send,recv收发消息,udp套接字使用sendto,recvfrom
 
-  使用场景 - tcp更适合对准确性要求高,传输数据较大的场景 - 文件传输:如下载电影,访问网页,上传照片
- 邮件收发
- 点对点数据传输:如点对点聊天,登录请求,远程访问,发红包
 
- udp更适合对可靠性要求没有那么高,传输方式比较自由的场景 - 视频流的传输: 如部分直播,视频聊天等
- 广播:如网络广播,群发消息
- 实时传输:如游戏画面
 
- 在一个大型的项目中,可能既涉及到TCP网络又有UDP网络
 
- tcp更适合对准确性要求高,传输数据较大的场景 
"""
完成一个对话小程序,客户端可以发送问题给服务端,
服务端接收到问题将对应答案给客户端,客户端打印出来
要求可以同时多个客户端提问,如果问题没有指定答案,
则回答 “人家还小,不知道。”注意: 不需要使用数据库文件存储应答内容,
在服务端用字典表示关键字和答案之间的对应关系即可
{"key":"value"}
key: 几岁
value : 我2岁啦
"""
from socket import *# 问答小字典
answer = {"你好": "你好啊","几岁": "我两岁啦","叫什么": "我叫小美","漂亮": "我当然漂亮啦","男生女生": "我是机器人"
}def chat(conn):q = conn.recv(1024).decode()# 查找关键词是否在问题中for key, val in answer.items():if key in q:conn.send(val.encode())breakelse:conn.send("人家还小,不知道啦".encode())def main():tcp_socket = socket(AF_INET, SOCK_STREAM)tcp_socket.bind(("0.0.0.0", 8888))tcp_socket.listen(5)# 循环处理问题while True:conn, addr = tcp_socket.accept()chat(conn)  # 处理问题回复conn.close()if __name__ == '__main__':main()#########################################################################"""
tcp 客户端
"""
from socket import *# 服务器地址
ADDR = ("127.0.0.1", 8888)def chat(msg):tcp_socket = socket()  # 创建套接字tcp_socket.connect(ADDR)tcp_socket.send(msg.encode())data = tcp_socket.recv(1024)print("小美:", data.decode())tcp_socket.close()def main():while True:msg = input("我:")if not msg:breakchat(msg)if __name__ == '__main__':main()tcp粘包问题
tcp按字节数接收消息,超出时,分多次接收,不足时一次性接收,产生粘包,一次性接收多个消息。解决:增加消息边界换行\n 或 加大发送时间间隔。
"""
实验:tcp
客户端有一个列表,列表中是一组学生信息
stu=["Tom:18:89","Lily:17:88","Jame:18:90"]
将这写信息发送到服务端,服务端在终端打印出来,
每个信息项打印一行
"""
#########################server
from socket import *# 监听套接字
sock = socket()
sock.bind(("0.0.0.0", 8888))
sock.listen(5)# 连接客户端
conn, addr = sock.accept()
print("Connect from", addr)
# 循环收 收一个打印一个
while True:data = conn.recv(1024)     #字节数较小时分多次接收,不一定与发的次数保持一致if data == b"##":breakprint(data.decode())# while True:
#     data = conn.recv(5)
#     if not data:
#         break
#     print(data.decode())conn.close()
sock.close()##########################client
from socket import *
from time import sleepstu = ["Tom:18:89","Lily:17:88","Jame:18:90"
]
sock = socket()
sock.connect(("127.0.0.1", 8888))# 循环发送内容 最后 ##  表示发送完毕
for row in stu:sock.send((row + "\n").encode())  # 增加消息边界 不加\n产生tcp粘包问题#tcp按conn.recv(1024)的字节数接收,超出时,多次接收,不足时一次性接收,产生粘包#udp按条接收不存在
sleep(0.1)  # 发送延迟  防止粘包
sock.send(b"##")# sock.send(b"Hello world")sock.close()加大发送时间间隔防止粘包
"""
假设在客户端有一张照片,请使用tcp
上传到服务端,在服务端以 20210909.jpeg 保存,带有上传成功回复plus : 假设文件比较大,不宜一次行读取全部内容思路: 读取数据 发送接收数据 写入
"""
from socket import *# 做事 : 收一个文件
def handle(conn):fw = open("../day11/20210909.jpeg", 'wb')while True:data = conn.recv(1024)if data == b'##':break  # 对方发送完成直接退出得到空字串fw.write(data)fw.close()conn.send("您已上传成功".encode())# 搭建网络模型
def main():# 创建监听套接字sock = socket()sock.bind(("0.0.0.0", 8888))sock.listen(5)# 循环接收连接while True:conn, addr = sock.accept()print("Connect from", addr)handle(conn)  # 具体的文件处理conn.close()if __name__ == '__main__':main()#################################client
from socket import *
from time import sleepADDR = ("127.0.0.1", 8888)def handle(sock):fr = open("/home/下载/reba.jpeg", 'rb')while True:data = fr.read(1024)if not data:break  # 文件结尾结束sock.send(data)fr.close()sleep(0.1)      #防止粘包操作sock.send(b'##')  # 表示告知已经发送完成data = sock.recv(1024)  # 接收最后的“上传成功提示”print(data.decode())def main():sock = socket()sock.connect(ADDR)handle(sock)  # 发送文件sock.close()if __name__ == '__main__':main()数据传输过程
传输流程
- 发送端由应用程序发送消息,逐层添加首部信息,最终在物理层发送消息包。
- 发送的消息经过多个节点(交换机,路由器)传输,最终到达目标主机。
- 目标主机由物理层逐层解析首部消息包,最终到应用程序呈现消息。
TCP协议首部信息
-  源端口和目的端口 各占2个字节,分别写入源端口和目的端口。 
-  序号seq 占4字节。TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。例如,一报文段的序号是301,而接待的数据共有100字节。这就表明本报文段的数据的第一个字节的序号是301,最后一个字节的序号是400。 
-  确认号ack 占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如,B正确收到了A发送过来的一个报文段,其序号字段值是501,而数据长度是200字节(序号501~700),这表明B正确收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。 
-  flags: ACK SYN FIN 确认ACK(ACKnowledgment) 仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。 同步SYN(SYNchronization) 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1,因此SYN置为1就表示这是一个连接请求或连接接受报文。 终止FIN(FINis,意思是“完”“终”) 用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。 
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MP81XITR-1682691580330)(picture\tcp_head.png)]
三次握手四次挥手
三次握手(建立连接)客户端向服务器发送消息报文请求连接  SYN=1   seq=x服务器收到请求后,回复报文确定可以连接 SYN=1  ACK=1 ack=x+1   seq=y客户端收到回复,发送最终报文连接建立  ACK=1 ack=y+1四次挥手(断开连接,都可以客气,客服端发起较多,有可能不能完成)主动方发送报文请求断开连接  FYN=1   seq=x被动方收到请求后,立即应答,表示准备断开 ACK=1 ack=x+1   seq=y被动方准备就绪,再次发送报文表示可以断开 FYN=1 ACK=1 ack=x+1 seq=Z主动方收到确定,发送最终报文完成断开 ACK=1 ack=z+1  seq=h
相关文章:
pt13网络编程
网络编程 OSI 7层模型 建立了统一的通信标准 降低开发难度,每层功能明确,各司其职 七层模型实际规定了每一层的任务,该完成什么事情 TCP/IP模型 七层模型过于理想,结构细节太复杂在工程中应用实践难度大实际工作中以TCP/IP模型…...
华为云 绑定/更换证书
操作场景 为了支持HTTPS数据传输加密认证,在创建HTTPS协议监听的时候需绑定证书,您可以参考本章节绑定证书。如果弹性负载均衡实例使用的证书过期或者其它原因需要更换,您可以参考本章节更换证书。如果还有其他的服务也使用了待更换的证书&a…...
 
重大问题,Windows11出现重大BUG
重大问题,Windows11出现重大BUG 这种Windows11操作系统出现BUG已经可以说是非常常见的,但是,今天我将代表所有微软用户,解决一个关于UI设计非常不舒服的功能 关闭多平面覆盖 事情叙述问题 微软社区解决方案自己发现的解决方案解决…...
 
傅里叶变换解析
p.s.本文无论是cos还是sin,都统一用“正弦波”(Sine Wave)一词来代表简谐波。 一、什么是频域 从我们出生,我们看到的世界都以时间贯穿,股票的走势、人的身高、汽车的轨迹都会随着时间发生改变。这种以时间作为参照来观察动态世界的方法我们称…...
你的登录接口真的安全吗?
1.前言 大家学写程序时,第一行代码都是hello world。但是当你开始学习WEB后台技术时,很多人的第一个功能就是写的登录 (小声:别人我不知道,反正我是)。但是我在和很多工作经验较短的同学面试或沟通的时候&…...
 
ChatGPT情商很高,但并不适合当搜索引擎
微软和谷歌正急于使用大型语言模型技术来强化搜索引擎。但有充分的理由认为,相比于提供事实性信息,这项技术更适合作为人们情感上的伴侣。 美媒评论称,目前基于大型语言模型的人工智能工具,例如ChatGPT,更擅长共情而不…...
Mac 地址与 IP 地址有什么区别?
Mac 地址和 IP 地址是两个不同的概念,它们分别代表了计算机网络中的不同层次和地址。Mac 地址是物理地址,是在计算机硬件中存储的地址,通常是以特定的六进制格式表示。每个设备都有一个唯一的 MAC 地址,它可以用来在计算机之间进行…...
bootloaders
什么是BootLoader? 一般来说,bootloader是一种软件/固件,它在SoC上电后立即运行。bootloader的主要职责是启动软件的后续部分,例如操作系统、baremetal应用程序或在某些情况下另一个bootloader。当涉及到嵌入式时,bootloader通常…...
 
PC或服务器装双系统
1. 准备工作 1.1U盘启动盘的制作 ①准备一个 4G 以上的 U 盘,备份好U盘资料,后面会对 U 盘进行格式化。 ②去CentOS官网下载你想要安装的 ISO 格式镜像文件,现在通常是CentOS6、7或者8。如果你英文不太好,可以选择使用edge浏览…...
 
嵌入式代码查看分析利器---Understand
平时在开发嵌入式程序的时候大多数使用的都是keil软件,一般小的工程使用keil没感觉到有什么问题,但是当工程比较大的时候,比如移植了FreeRTOS系统或者LWIP网络系统时,代码全部编译一次就要花费很长世间,特别是开启了点…...
 
人群计数经典方法Density Map Estimation,密度图估计
(3)Density Map Estimation(主流) 这是crowd counting的主流方法 传统方法不好在哪里?object detection-based method和regression-based method无法从图像中提取更抽象的有助于完成人群计数任务的语义特征 概况&…...
【华为】Smart-Link基础知识
Smark-Link技术 Smark-Link(灵活链路or备份链路,华为/华三 私有用) Smark-Link定义 Smark-Link,又叫备份链路。一个Smark Link由两个接口组组成,其中一个接口作为另一个的备份。Smark-Link常用于双上行组网,提供可靠高效的备份与…...
 
分享24个强大的HTML属性 —— 建议每位前端工程师都应该掌握
前期回顾 是不是在为 API 烦恼 ?好用免费的api接口大全呼之欲出_0.活在风浪里的博客-CSDN博客APi、常用框架、UI、文档—— 整理合并https://blog.csdn.net/m0_57904695/article/details/130459417?spm1001.2014.3001.5501 👍 本文专栏:…...
 
NIO基础 - 网络编程
non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 stream 要么是输入…...
06.toRef 和 toRefs
学习要点: 1.toRef 和 toRefs 本节课我们来要了解一下 Vue3.x 中的 ref 两个周边 API 的用法; 一.toRef 和 toRefs 1. toRef 可以将源响应式对象上的 property 创建一个 ref 对象; const obj reactive({ name : Mr.Lee, age : 10…...
 
RabbitMq、Kafka、RocketMq整理
MQ的主要作用:异步提高性能、解耦提高扩展性、削峰。 一、常见中间件对比 Kafka、RocketMq和RabbitMq最大的区别就是:前两个是分布式存储。 1.1、ActiveMq 优点:1)完全支持jms规范的消息中间件 ,2)提供丰富的api, 3)多种集群构建模式。 缺点:)在高并发的场景下,性能可…...
 
Python多元线性回归预测模型实验完整版
多元线性回归预测模型 实验目的 通过多元线性回归预测模型,掌握预测模型的建立和应用方法,了解线性回归模型的基本原理 实验内容 多元线性回归预测模型 实验步骤和过程 (1)第一步:学习多元线性回归预测模型相关知识。 一元线性回归模型…...
C#基础 变量在内存中的存储空间
变量存储空间(内存中) // 1byte 8bit // 1KB 1024byte // 1MB 1024KB // 1GB 1024MB // 1TB 1024GB // 通过sizeof方法 可以获取变量类型所占的内存空间(单位:字节) 有…...
 
你最关心的4个零代码问题,ChatGPT 帮你解答了!
作为人工智能(AI)新型聊天机器人模型 ChatGPT,刚上线5天就突破100万用户,两个多月全球用户量破亿,不愧为业界最炙热的当红炸子鸡。 ChatGPT 是一种语言生成模型,由 OpenAI 开发和训练。它是基于 Transform…...
linux的环境变量
目录 一、自定义变量和环境变量的区别 二、自定义变量 三、环境变量 四、查看所有变量(自定义变量、环境变量) 五、记录环境变量到相关的系统文件 (1)为什么要这样做? (2)环境变量相关系统…...
 
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
 
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
 
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
 
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
 
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
