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

12 正则表达式 | HTTP协议相关介绍

文章目录

  • 正则表达式
    • re模块最基础操作(匹配开头)
    • 匹配单个字符
    • 匹配多个字符
    • 匹配开头结尾
    • 匹配分组
    • 对于group的理解
    • r的作用
    • re 模块高级用法
      • compile
      • search
      • findall
        • 易错点
      • sub
        • 直接替换
        • 函数替换
      • split 根据匹配进行切割字符串,并返回一个列表
    • python 贪婪和非贪婪
  • HTTP 协议
    • 对于F12的一些组件介绍
    • 浏览器解析过程
    • http 协议的结束符
    • B/S模式下的Web静态服务器
      • Web 静态服务器-1-显示固定的页面
      • Web 静态服务器-2-显示需要的页面
      • Web 静态服务器-3-多进程
      • Web 静态服务器-4-多线程
      • Web 静态服务器-5-非堵塞模式
      • Web 静态服务器-6-epoll
      • Web 静态服务器-7-gevent 版

正则表达式

在 Python 中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为 re。

re模块最基础操作(匹配开头)

# 导入 re 模块
import re
# 使用 match 方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用 group 方法来提取数据
result.group()

示例:

import reresult = re.match("helloworld","helloworld.cn")print(result.group())

输出的结果:

helloworld

说明:re.match() 能够匹配出以== xxx 开头==的字符串

匹配单个字符

字符功能
.匹配任意 1 个字符(除了\n)
[ ]匹配[ ]中列举的字符
\d匹配数字,即 0-9 dicimal
\D匹配非数字,即不是数字
\s匹配空白,即 空格,tab 键 space
\S匹配非空白
\w匹配单词字符,即 a-z、A-Z、0-9、_ (汉字) word
\W匹配非单词字

示例:

import reret = re.match("t.o","two")
print(ret.group())# 大小写 h 都可以的情况
ret = re.match("[hH]","hello Python")
print(ret.group())# 匹配 0 到 9 第二种写法
ret = re.match("[0-9]Hello Python","7Hello Python")
print(ret.group())
ret = re.match("[0-35-9]Hello Python","7Hello Python")
print(ret.group())# 使用\d 进行匹配
ret = re.match("嫦娥\d 号","嫦娥 1 号发射成功")
print(ret.group())# 等等

匹配多个字符

字符功能
*匹配前一个字符出现 0 次或者无限次,即可有可无
+匹配前一个字符出现 1 次或者无限次,即至少有 1 次
?匹配前一个字符出现 1 次或者 0 次,即要么有 1 次,要么没有
{m}匹配前一个字符出现 m 次
{m,n}匹配前一个字符出现从 m 到 n 次

示例:

import re# *的功能实现
ret = re.match("[A-Z][a-z]*","Aabcdef")
print(ret.group())
# 输出结果:Aabcdef# +的功能实现
names = ["name1", "_name", "2_name", "__name__"]
for name in names:ret = re.match("[a-zA-Z_]+[\w]*",name)
if ret:print("变量名 %s 符合要求" % ret.group())
else:print("变量名 %s 非法" % name)
# 输出结果:
# 变量名 name1 符合要求
# 变量名 _name 符合要求
# 变量名 2_name 非法
# 变量名 __name__ 符合要求# ?的功能实现
ret = re.match("[1-9]?\d","09")
print(ret.group())
# 输出结果:0# {m}的功能实现
ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66")
print(ret.group())
# 输出结果:1ad12f23s34455ff66

匹配开头结尾

字符功能
^匹配字符串开头
$匹配字符串结尾

示例:

email_list = ["xiaoWang@163.com","xiaoWang@163.comheihei",".com.xiaowang@qq.com"]
for email in email_list:ret = re.match("[\w]{4,20}@163\.com$", email)if ret:print("%s 是符合规定的邮件地址,匹配后的结果是:%s" %(email,ret.group()))else:print("%s 不符合要求" % email)

或者说,实际上我们仅需要所有情况下在最前面加上^ 最后面加上$也可以解决大多数问题。

匹配分组

字符功能
|匹配左右任意一个表达式
(ab)将括号中字符作为一个分组
\num引用分组 num 匹配到的字符串
(?P<name>)分组起别名
(?P=name)引用别名为 name 分组匹配到的字

[^符号]* 代表没有遇到符号就一直进行匹配,一直匹配下去

例子:

import re# |的使用
ret = re.match("[1-9]?\d$|100","100")
print(ret.group()) 
# 输出:100# ()分组的使用
ret = re.match("\w{4,20}@(163|126|qq)\.com", "test@126.com")
print(ret.group()) 
# 输出:test@126# ([^-]*) 代表没有遇到小横杠-就一直进行匹配,一直匹配下去
ret = re.match("([^-]+)-(\d+)","010-12345678")
print(ret.group())
# 输出:'010-12345678'# 使用\num,需要注意的是,这边需要使用元字符串,即类似 r""这种格式
ret = re.match(r"<([a-zA-Z]*)>\w*</\1>", "<html>hh</html>")
print(ret.group())# (?P<name>) (?P=name)
# 注意P要大写
ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>","<html><h1>www.qq.com</h1></html>")
print(ret.group())
# 输出:<html><h1>www.qq.com</h1></html>

对于group的理解

实际上:

re.group(0)和re.group()输出的是符合的正则表达式的东西
re.group(1)输出的的是第一个分组内的东西(如果有分组才有这一项,没有的话就无这一项)

r的作用

Python 中字符串前面加上 r 表示原生字符串,

与大多数编程语言相同,正则表达式里使用"“作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符”“,那么使用编程语言表示的正则表达式里将需要 4 个反斜杠”\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。

Python 里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

值得关注的是这个r只解决了//,就是只对/生效,如果需要匹配.,实际上也需要使用转义/.

re 模块高级用法

compile

compile实际上就是为了避免写这个正则表达式的式子太长,每次都要进行书写,就先把这个封装成一个对象,然后调用这个对象里面的方法进行使用。

com = re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(?:0[0-9]|1[0-9]|2[0-4])\:[0-5][0-9]')
com.match('2020/7/20 18:20')

search

功能:使用正则匹配式去字符串中寻找第一个符合该格式的子串

import re
ret = re.search(r"\d+", "阅读次数为 9999")
print(ret.group())

输出:

9999

findall

功能:寻找字符串中所有符合正则表达式的字串

基础样例:

import re
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)

输出(值得关注的是返回的是一个列表,而非一个对象,然后使用group方法进行调用):

['9999', '7890', '12345']

易错点

对于包含分组的正则表达式,findall会去匹配分组内的正则表达式。

ret_s = hello world, now is 2020/7/20 18:48, 现在是2020/7/20 18:48
# compile避免了每次都去写正则,findall 有问题
com = re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(0[0-9]|1[0-9]|2[0-4]):[0-5][0-9]')
ret = com.findall(ret_s)
print(ret)# ?:可以避免findall只提取分组内的内容
com1 = re.compile(r'\d{4}/[01]?[0-9]/[1-3]?[0-9]\s(?:0[0-9]|1[0-9]|2[0-4]):[0-5][0-9]')
ret = com1.findall(ret_s)
print(ret)

输出:

['18', '18']
['2020/7/20 18:48', '2020/7/20 18:48']

sub

功能:替换字符串

直接替换

import re
s = 'hello world, now is 2020/7/20 18:48, 现在是 2020 年 7 月 20 日 18 时 48 分。'
ret_s = re.sub(r'年|月', r'/', s)
ret_s = re.sub(r'日|分', r' ', ret_s)
ret_s = re.sub(r'时', r':', ret_s)
print(ret_s)

输出:

hello world, now is 2020/7/20 18:48, 现在是2020/7/20 18:48

函数替换

不论使用匿名函数还是使用真实的函数都是可以的,唯一值得关注的是传进来的对象是正则表达式匹配后的字符串类型的数据,如果需要整形化处理,记得加上int(),最后也需要返回str()类型的数据

import redef add(temp):strNum = temp.group()num = int(strNum) + 1return str(num)ret = re.sub(r"\d+", add, "python = 997")
print(ret)ret = re.sub(r"\d+", lambda temp: str(int(temp.group()) + 1), "python = 99")
print(ret)

split 根据匹配进行切割字符串,并返回一个列表

import re
ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)

python 贪婪和非贪婪

Python 里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。

解决方式:非贪婪操作符“?”,这个操作符可以用在"*“,”+“,”?"的后面,要求正则匹配的越少越好。

test_str='''
<img data-original="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">
'''
# 贪婪的写法,最后得到的数据会匹配到最后一个jpg,实际上就是*一直吃到最后
print(re.search(r"https://.*\.jpg",test_str).group())
# 非贪婪的写法,最后得到的数据会匹配到最开始的一个jpg
print(re.search(r"https://.*?\.jpg", test_str).group())

输出结果:

https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg
https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg

HTTP 协议

对于F12的一些组件介绍

监测一下百度官网(这边采用edge浏览器,其他的用谷歌的也是差不多的。)
在这里插入图片描述
Elements 显示网页的结构
Network 显示浏览器和服务器的通信

我们点 Network,确保第一个小红灯亮着,浏览器就会记录所有浏览器和服务器之间的通信。
在这里插入图片描述

点开即可查看对应的是什么,然后进行对比以下的格式会有更深的领悟,这边列一下我这边接受到百度http协议的包,并对于比较重要的概念的介绍。

General(常规):

Request URL:		https://www.baidu.com/
Request Method:		GET
Status Code:		200 OK
Remote Address:		36.152.44.96:443
Referrer Policy:	unsafe-url
  1. Request URL:即你请求的网站
  2. Request Method:请求资源的方法,一般请求资源的方法有四种:get(查询),post(新增),put(修改),delete(删除)
  3. Status Code:状态,200代表成功返回响应
  4. Remote Address:远程连接多少ip的多少port,而我们采用http即都是80端口,https是443端口
  5. Referrer Policy:来源页面政策,暂时不用了解,想要了解,可以百度

Response header(响应标头)这一部分就是服务器返回来的数据header

HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0x87d5ef110007ca38
Connection: keep-alive
Content-Encoding: gzip
Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
Content-Type: text/html; charset=utf-8
Date: Tue, 15 Aug 2023 06:17:21 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=36544_39107_38831_26350_39138_39132_39100; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 169208024116233405549787992221453634104
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked

HTTP 响应分为 Header 和 Body 两部分(Body 是可选项),我们在 Network 中看到的 Header 最重要的几行如下:

  1. HTTP/1.1 200 OK
    200 表示一个成功的响应,后面的 OK 是说明。
    如果返回的不是 200,那么往往有其他的功能,例如
    1.1 失败的响应有 404 Not Found:网页不存在
    1.2 500 Internal Server Error:服务器内部出错
    1.3 …等等…
  2. Content-Type: text/html
    Content-Type 指示响应的内容,这里是 text/html 表示 HTML 网页。请注意,浏览器就是依靠 Content-Type 来判断响应的内容是网页还是图片,是视频还是音乐。浏览器并不靠 URL 来判断响应的内容,所以,即使 URL 是http://www.baidu.com/meimei.jpg,它也不一定就是图片。
  3. HTTP 响应的 Body 就是 HTML 源码,我们在菜单栏选择“视图”,“开发者”,“查看网页源码”就可以在浏览器中直接查看 HTML 源码
  4. Connection: keep-alive当中代表连接是长连接,也就是说你与服务器会保持连接,不会像短链接一样,仅仅在使用的时候connect服务器,发送完数据之后就结束连接
  5. Transfer-Encoding: chunked流式文件后面介绍

Request Header(请求头)这就是浏览器发给服务器的数据,因为这些数据是有格式的,所以就称作http协议

GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cache-Control: max-age=0
Connection: keep-alive
Cookie: 这边有一串数据,里面包含了token等等一系列东西
Host: www.baidu.com
Referer: https://www.baidu.com/s?tn=15007414_9_dg&wd=%E7%99%BE%E5%BA%A6
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.200
sec-ch-ua: "Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

最主要的头两行分析如下,第一行:

  1. GET / HTTP/1.1
    GET 表示一个读取请求,将从服务器获得网页数据,/表示 URL 的路径,URL 总是以/开头,/就表示首页,最后的 HTTP/1.1 指示采用的 HTTP 协议版本是 1.1。目前 HTTP 协议的版本就是 1.1,但是大部分服务器也支持 1.0 版本,主要区别在于 1.1 版本允许多个 HTTP 请求复用一个 TCP 连接,以加快传输速度。
  2. 从第二行开始,每一行都类似于 Xxx: abcdefg:
  3. Host: www.sina.com
    表示请求的域名是 www.baidu.com。如果一台服务器有多个网站,服务器就需要通过 Host 来区分浏览器请求的是哪个网站

浏览器解析过程

当浏览器读取到新浪首页的 HTML 源码后,它会解析 HTML,显示页面,然后,根据 HTML 里面的各种链接,再发送 HTTP 请求给新浪服务器,拿到相应的图片、视频、JavaScript 脚本、CSS 等各种资源,最终显示出一个完整的页面。所以我们在 Network 下面能看到很多额外的 HTTP 请求
在这里插入图片描述

http 协议的结束符

http 的 header 和 body 之间空行分割的,又因为每个头部项是以 \r\n 作为结束符,所以,数据流中是以 \r\n\r\n 来分割解析请求头(响应头)与请求体(响应体)的。如下图所示:
在这里插入图片描述
理解一下使用/r/n/r/n进行隔断数据,但是现在这一句话也不是很正确,这边写者也只是粗浅理解。

补充:链接

B/S模式下的Web静态服务器

我们这边写的代码属于的就是web服务器端,算作对于前面网络编程epoll,进程池,线程池,协程的综合,虽然不如web服务器端常用的框架apache和nginx,但写一下还是有利于自己对于http协议以及一系列网络编程的理解:

在这里插入图片描述

Web 静态服务器-1-显示固定的页面

#! /bin/usr/python3.6
# 编辑人:lgt
# 时间2023年08月15日import socketdef tcp_server():# 创建socket对象tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 复用端口tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# bindtcp_server.bind(('',2000))# listentcp_server.listen(128)# 阻塞连接等待连接对象client,client_arr = tcp_server.accept()# 接收消息http_head = client.recv(10000)print(http_head.decode('utf-8'))# 连接之后,这边默认直接返回一个前端的页面,第一个demo不搞太难# response头的标准写法  每行的结束以\r\n为标志response = "HTTP/1.1 200 OK\r\n"# 多加个\r\n代表协议头结束response += "\r\n"# 此时加上body的内容response += '<html><h1>hello world</h1></html>'# 传回消息client.send(response.encode('utf-8'))client.close()# 这边就不关闭tcp服务器了if __name__ == '__main__':tcp_server()

输出过去给浏览器的:
在这里插入图片描述

此时打开ipconfig进行查看,然后使用浏览器进行访问端口,即可看到对应的页面。

此时服务器端口能发现返回了这一个协议属性,所以我们可以再次进行相对应的修改
在这里插入图片描述

Web 静态服务器-2-显示需要的页面

这里我们思考一个问题,如果我们采用单进程有没有可能可以多个网页进行和服务器进行沟通,得到页面请求?

直觉告诉我们是不太可能的,原因就是我们的思想背局限在长连接上了,在短连接的情况下是完全可以做到的,下面就是使用单进程,短连接的方式进行写的。

import socket
import redef tcp_server():"""tcp_server的创建:return: None"""# 创建socket对象tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 复用端口tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# bindtcp_server.bind(('',2000))# listentcp_server.listen(128)while True:# 阻塞连接等待连接对象client,client_arr = tcp_server.accept()solve_task(client)# 关闭tcp服务器,实际上没有关闭,原因就是上面的是死循环tcp_server.close()def solve_task(client:socket):"""实现http协议传输以及接受需求的对应的网页资源的返回:param client:客户端:return:None"""# 接收消息print('*' * 100)http_head = client.recv(10000)print(http_head.decode('utf-8'))# 定义正则表达式,提取print('*' * 100)# [^/]*吞掉/之前所有的字符,后面重要部分使用()进行括起来,后面使用group(1)进行提取re1 = re.compile(r'[^/]*(/[^ ]*)')file1 = re1.match(http_head.decode('utf-8')).group(1)print(file1)if file1 == '/':file1 = '/index.html'# 拿到了想要返回的html的样式,这时候就应该返回相关的数据try:f = open('./html' + file1 , 'rb')except:# 如果文件没有找到response = "HTTP/1.1 404 NOT FOUND\r\n"# 多加个\r\n代表协议头结束response += "\r\n"response += "<html><h1>------file not found-----</h1></html>"client.send(response.encode("utf-8"))else:# 如果文件找到了# response头的标准写法  每行的结束以\r\n为标志response = "HTTP/1.1 200 OK\r\n"# 多加个\r\n代表协议头结束response += "\r\n"# 此时加上body的内容body = f.read()f.close()# 传回消息client.send(response.encode('utf-8'))client.send(body)# 此处是关键,判断短连接的重要标志client.close()if __name__ == '__main__':tcp_server()

Web 静态服务器-3-多进程

import socket
import re
from multiprocessing import Process
def tcp_server():"""tcp_server的创建:return: None"""# 创建socket对象tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 复用端口tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# bindtcp_server.bind(('',2000))# listentcp_server.listen(128)while True:# 阻塞连接等待连接对象client,client_arr = tcp_server.accept()# 值得关注的是args=(client,)需要有一个,p = Process(target=solve_task,args=(client,))p.start()# 此处为什么要关掉呢?这里因为我们使用的是进程,对于进程来说,资源属于引入计数,也就是别的进程到这里是复制主进程的所有的变量,再进去的,此时主进程就可以关掉了client.close()# 关闭tcp服务器,实际上没有关闭,原因就是上面的是死循环tcp_server.close()def solve_task(client:socket):"""实现http协议传输以及接受需求的对应的网页资源的返回:param client:客户端:return:None"""# 接收消息print('*' * 100)http_head = client.recv(10000)print(http_head.decode('utf-8'))# 定义正则表达式,提取print('*' * 100)# [^/]*吞掉/之前所有的字符,后面重要部分使用()进行括起来,后面使用group(1)进行提取re1 = re.compile(r'[^/]*(/[^ ]*)')file1 = re1.match(http_head.decode('utf-8')).group(1)print(file1)if file1 == '/':file1 = '/index.html'# 拿到了想要返回的html的样式,这时候就应该返回相关的数据try:f = open('./html' + file1 , 'rb')except:# 如果文件没有找到response = "HTTP/1.1 404 NOT FOUND\r\n"# 多加个\r\n代表协议头结束response += "\r\n"response += "<html><h1>------file not found-----</h1></html>"client.send(response.encode("utf-8"))else:# 如果文件找到了# response头的标准写法  每行的结束以\r\n为标志response = "HTTP/1.1 200 OK\r\n"# 多加个\r\n代表协议头结束response += "\r\n"# 此时加上body的内容body = f.read()f.close()# 传回消息client.send(response.encode('utf-8'))client.send(body)# 此处是关键,判断短连接的重要标志client.close()if __name__ == '__main__':tcp_server()

Web 静态服务器-4-多线程

#! /bin/usr/python3.6
# 编辑人:lgt
# 时间2023年08月15日import socket
import re
import threading
def tcp_server():"""tcp_server的创建:return: None"""# 创建socket对象tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 复用端口tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)# bindtcp_server.bind(('',2000))# listentcp_server.listen(128)while True:# 阻塞连接等待连接对象client,client_arr = tcp_server.accept()# 值得关注的是args=(client,)需要有一个,p = threading.Thread(target=solve_task,args=(client,))p.start()# 多线程时,client传递给子线程以后,主线程不能关闭# client.close()# 关闭tcp服务器,实际上没有关闭,原因就是上面的是死循环tcp_server.close()def solve_task(client:socket):"""实现http协议传输以及接受需求的对应的网页资源的返回:param client:客户端:return:None"""# 接收消息print('*' * 100)http_head = client.recv(10000)print(http_head.decode('utf-8'))# 定义正则表达式,提取print('*' * 100)# [^/]*吞掉/之前所有的字符,后面重要部分使用()进行括起来,后面使用group(1)进行提取re1 = re.compile(r'[^/]*(/[^ ]*)')file1 = re1.match(http_head.decode('utf-8')).group(1)print(file1)if file1 == '/':file1 = '/index.html'# 拿到了想要返回的html的样式,这时候就应该返回相关的数据try:f = open('./html' + file1 , 'rb')except:# 如果文件没有找到response = "HTTP/1.1 404 NOT FOUND\r\n"# 多加个\r\n代表协议头结束response += "\r\n"response += "<html><h1>------file not found-----</h1></html>"client.send(response.encode("utf-8"))else:# 如果文件找到了# response头的标准写法  每行的结束以\r\n为标志response = "HTTP/1.1 200 OK\r\n"# 多加个\r\n代表协议头结束response += "\r\n"# 此时加上body的内容body = f.read()f.close()# 传回消息client.send(response.encode('utf-8'))client.send(body)# 此处是关键,判断短连接的重要标志client.close()if __name__ == '__main__':tcp_server()

Web 静态服务器-5-非堵塞模式

import time
import socket
import sys
import reclass WSGIServer(object):"""定义一个WSGI服务器的类"""def __init__(self, port, documents_root):# 1. 创建套接字self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2. 绑定本地信息self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.server_socket.bind(("", port))# 3. 变为监听套接字self.server_socket.listen(128)self.server_socket.setblocking(False)self.client_socket_list = list()self.documents_root = documents_rootdef run_forever(self):"""运行服务器"""# 等待对方链接while True:# time.sleep(0.5)  # for test#下面try的目的是接收请求并放入列表try:new_socket, new_addr = self.server_socket.accept()except Exception as ret:# print("-----1----", ret)  # for testpasselse:print(time.time())new_socket.setblocking(False)self.client_socket_list.append(new_socket)#遍历列表中的连接,如果有浏览器发过来数据,那么就处理for client_socket in self.client_socket_list:try:request = client_socket.recv(4096).decode('utf-8')except Exception as ret:# print("------2----", ret)  # for testpasselse:if request:#有数据就处理数据self.deal_with_request(request, client_socket)else:#浏览器断开了client_socket.close()self.client_socket_list.remove(client_socket)print(time.time())# print(self.client_socket_list)def deal_with_request(self, request, client_socket):"""为这个浏览器服务器"""if not request:returnrequest_lines = request.splitlines()#这个for循环是为了打印看数据# for i, line in enumerate(request_lines):#     print(i, line)# 提取请求的文件(index.html)# GET /a/b/c/d/e/index.html HTTP/1.1ret = re.match(r"([^/]*)([^ ]+)", request_lines[0])if ret:# print("正则提取数据:", ret.group(1))# print("正则提取数据:", ret.group(2))file_name = ret.group(2)if file_name == "/":file_name = "/index.html"# 读取文件数据try:f = open(self.documents_root+file_name, "rb")except:response_body = "file not found, 请输入正确的url"response_header = "HTTP/1.1 404 not found\r\n"response_header += "Content-Type: text/html; charset=utf-8\r\n"response_header += "Content-Length: %d\r\n" % (len(response_body))response_header += "\r\n"# 将header返回给浏览器client_socket.send(response_header.encode('utf-8'))# 将body返回给浏览器client_socket.send(response_body.encode("utf-8"))else:content = f.read()f.close()response_body = contentresponse_header = "HTTP/1.1 200 OK\r\n"response_header += "Content-Length: %d\r\n" % (len(response_body))response_header += "\r\n"# 将header返回给浏览器client_socket.send( response_header.encode('utf-8') + response_body)# 设置服务器服务静态资源时的路径
DOCUMENTS_ROOT = "./html"def main():"""控制web服务器整体"""# python3 xxxx.py 7890if len(sys.argv) == 2:port = sys.argv[1]if port.isdigit():port = int(port)else:print("运行方式如: python3 xxx.py 7890")returnprint("http服务器使用的port:%s" % port)http_server = WSGIServer(port, DOCUMENTS_ROOT)http_server.run_forever()if __name__ == "__main__":main()

Web 静态服务器-6-epoll

import socket
import re
import selectdef service_client(new_socket, request):"""为这个客户端返回数据"""# 1. 接收浏览器发送过来的请求 ,即http请求  # GET / HTTP/1.1# .....# request = new_socket.recv(1024).decode("utf-8")# print(">>>"*50)# print(request)if not request:returnrequest_lines = request.splitlines()print("")print(">"*20)print(request_lines)if not request_lines:return# GET /index.html HTTP/1.1# get post put delfile_name = ""ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])if ret:file_name = ret.group(1)# print("*"*50, file_name)if file_name == "/":file_name = "/index.html"# 2. 返回http格式的数据,给浏览器try:f = open("./html" + file_name, "rb")except:response = "HTTP/1.1 404 NOT FOUND\r\n"response += "\r\n"response += "------file not found-----"new_socket.send(response.encode("utf-8"))else:html_content = f.read()f.close()response_body = html_contentresponse_header = "HTTP/1.1 200 OK\r\n"response_header += "Content-Length:%d\r\n" % len(response_body)response_header += "\r\n"response = response_header.encode("utf-8") + response_bodynew_socket.send(response)def main():"""用来完成整体的控制"""# 1. 创建套接字tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 2. 绑定tcp_server_socket.bind(("", 7890))# 3. 变为监听套接字tcp_server_socket.listen(128)tcp_server_socket.setblocking(False)  # 将套接字变为非堵塞# 创建一个epoll对象epl = select.epoll()# 将监听套接字对应的fd注册到epoll中epl.register(tcp_server_socket.fileno(), select.EPOLLIN)fd_event_dict = dict()while True:fd_event_list = epl.poll()  # 默认会堵塞,直到 os监测到数据到来 通过事件通知方式 告诉这个程序,此时才会解堵塞# [(fd, event), (套接字对应的文件描述符, 这个文件描述符到底是什么事件 例如 可以调用recv接收等)]for fd, event in fd_event_list:# 等待新客户端的链接if fd == tcp_server_socket.fileno():new_socket, client_addr = tcp_server_socket.accept()epl.register(new_socket.fileno(), select.EPOLLIN)fd_event_dict[new_socket.fileno()] = new_socket  #字典,键是filenoelif event==select.EPOLLIN:# 判断已经链接的客户端是否有数据发送过来#如何通过不遍历来定位socketrecv_data = fd_event_dict[fd].recv(4096).decode("utf-8")if recv_data:service_client(fd_event_dict[fd], recv_data)else:fd_event_dict[fd].close()epl.unregister(fd)del fd_event_dict[fd]  #从字典中移除# 关闭监听套接字tcp_server_socket.close()if __name__ == "__main__":main()

Web 静态服务器-7-gevent 版

import socket
import re
import gevent
from gevent import monkey# monkey组件
monkey.patch_all()def service_client(new_socket):'''为客户端返回数据'''# 接收http请求request = new_socket.recv(1024).decode('utf-8')if request:request_lines = request.splitlines()print("")print(">" * 20)print(request_lines)file_name = ""ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])if ret:file_name = ret.group(1)if file_name == "/":file_name = "/index.html"print(file_name)try:f = open("./html" + file_name, "rb")except:response = "HTTP/1.1 404 NOT FOUND\r\n"response += "\r\n"response += "-------file not found-------"new_socket.send(response)else:html_content = f.read()f.close()response = "HTTP/1.1 200 OK\r\n"response += "\r\n"new_socket.send(response.encode('utf-8'))new_socket.send(html_content)new_socket.close()def main():'''创建套接字'''# 初始化tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 绑定tcp_server_socket.bind(("", 7890))# 激活tcp_server_socket.listen(128)while True:new_socket, socket_addr = tcp_server_socket.accept()gevent.spawn(service_client, new_socket)tcp_server_socket.close()if __name__ == '__main__':main()

相关文章:

12 正则表达式 | HTTP协议相关介绍

文章目录 正则表达式re模块最基础操作&#xff08;匹配开头&#xff09;匹配单个字符匹配多个字符匹配开头结尾匹配分组对于group的理解r的作用re 模块高级用法compilesearchfindall易错点 sub直接替换函数替换 split 根据匹配进行切割字符串&#xff0c;并返回一个列表 python…...

【C语言】数组概述

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 &#x1f525;该篇将带你了解 一维数组&#xff0c;二维数组等相关知识。 目录&#xff1a; &#x1f4d8;前言&#xff1a;&#x1f…...

8. 实现业务功能--用户注册

目录 1. 顺序图 2. 参数要求 3. 接口规范 4. 创建扩展 Mapper.xml 5. 修改 DAO 6. 创建 Service 接口 7. 实现接口 8. 测试接口 9. 实现 Controller 9.1 密码加密处理 10. 实现前端界面 业务实现过程中主要的包和目录及主要功能&#xff1a; model 包&#xff1a;实体对象 d…...

深入浅出Pytorch函数——torch.nn.init.eye_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

版本控制工具Git集成IDEA的学习笔记(第一篇Gitee)

目录 一、Gitee的使用 1、注册网站会员 2、用户中心 3、创建远程仓库 4、配置SSH免密登录 二、集成IDEA&#xff0c;Git项目搭建 1、本地仓库搭建 1&#xff09;创建一个新项目 2&#xff09;打开终端&#xff0c;在当前目录新建一个Git代码库 3&#xff09;忽略文件 …...

【链表】 61. 旋转链表

61. 旋转链表 解题思路 首先计算出链表长度将链表长度进行取余遍历链表 对链表进行分割 得到两个子链表重新连接两个链表比如1 2 3 4 5 k 2 进行分割得到 1 2 3 和 4 5两个子链表 /*** Definition for singly-linked list.* public class ListNode {* int val;* Lis…...

深入浅出Pytorch函数——torch.nn.init.kaiming_uniform_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

查询Oracle和MySQL数据库中当前所有连接信息

查询Oracle当前所有连接信息&#xff1a; SELECTs.sid AS 会话ID,s.serial# AS 序列号,s.username AS 用户名,s.osuser AS 操作系统用户,s.machine AS 客户端机器,s.program AS 客户端程序,s.status AS 会话状态,s.sql_id AS 正在执行的SQL_ID,t.sql_text AS 正在执行的SQL文本…...

Android glide框架及框架涉及到的设计模式

目录 原文链接Android glide框架 简单使用介绍Glide 框架整体结构设计Glide 框架的优点基本使用&#xff1a;Glide占位符 Android glide框架涉及到的设计模式 原文链接 Android glide框架 简单使用介绍 Glide&#xff1a;快速高效的Android图片加载库&#xff0c;可以自动加载…...

使用yolov5进行安全帽检测填坑指南

参考项目 c​​​​​​​​​​​​​​GitHub - PeterH0323/Smart_Construction: Base on YOLOv5 Head Person Helmet Detection on Construction Sites&#xff0c;基于目标检测工地安全帽和禁入危险区域识别系统&#xff0c;&#x1f680;&#x1f606;附 YOLOv5 训练自己的…...

【BASH】回顾与知识点梳理(三十二)

【BASH】回顾与知识点梳理 三十二 三十二. SELinux 初探32.1 什么是 SELinux当初设计的目标&#xff1a;避免资源的误用传统的文件权限与账号关系&#xff1a;自主式访问控制, DAC以政策规则订定特定进程读取特定文件&#xff1a;委任式访问控制, MAC 32.2 SELinux 的运作模式安…...

vscode远程调试PHP代码

目录 一、准备工作 二、ssh连接和xdebug配置 1.ssh连接 2.xdebug配置 三、xdebug调试&#xff0c;访问 一、准备工作 1.安装vscode里面的两个扩展 2.安装对应PHP版本的xdebug 去xdebug官方&#xff0c;复制自己的phpinfo源码到方框里&#xff0c;再点击Analyse Xdebug: …...

flink1.17 实现 udf scalarFunctoin get_json_object 支持 非标准化json

特色 相比官方的json_value,该函数支持非标准化json,比如v是个object,但是非标准json会外套一层引号,内部有反引号. eg: {"kkkk2": "{\"kkkk1\":\"vvvvvvv\"}" } 支持value为 100L 这种java格式的bigint. {"k":999L…...

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)九:自定义组件封装下

一、本章内容 续上一张,本章实现一些自定义组件的封装,包括文件上传组件封装、级联选择组件封装、富文本组件封装等。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 基于VUE3+Layui从头搭建通用后台管...

设计模式详解-装饰器模式

类型&#xff1a;结构型模式 实现原理&#xff1a;装饰器模式通过将对象包装在装饰器类中&#xff0c;并在保持类方法签名完整性的前提下&#xff0c;提供额外功能 作用&#xff1a;动态地给一个对象添加一些额外的职责。增加功能方面&#xff0c;装饰器模式比生成子类更灵活…...

Android5:活动生命周期

创建项目Stopwatch activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_w…...

第2章 数据结构和算法概述

2.3线性结构和非线性结构 数据结构包括: 线性结构和非线性结构 2.3.1线性结构 线性结构作为最常用的数据结构&#xff0c;其特点是数据元素之间存在一对一的线性关系线性结构有两种不同的存储结构&#xff0c;即顺序存储结构(数组)和链式存储结构(链表)。顺序存储的线性表称…...

WPF国际化的实现方法(WpfExtensions.Xaml)

https://blog.csdn.net/eyupaopao/article/details/120090431 resx资源文件实现 resx资源文件&#xff0c;实现的过程比第一种复杂&#xff0c;但resx文件本身编辑比较简单&#xff0c;维护起来比较方便。需要用到的框架&#xff1a;WpfExtensions.Xaml 为每种语言添加.resx资…...

【Linux】—— 进程程序替换

目录 序言 &#xff08;一&#xff09;替换原理 1、进程角度——见见猪跑 1️⃣ 认识 execl 函数 2、程序角度——看图理解 &#xff08;二&#xff09;替换函数 1、命名理解 2、函数理解 1️⃣execlp 2️⃣execv 3️⃣execvp 4️⃣execle 5️⃣execve 6️⃣execve…...

idea创建javaweb项目,jboss下没有web application

看看下图这个地方有没有web application...

广东灯具3D扫描抄数建模服务3D测绘出图纸三维逆向设计-CASAIM

灯具三维逆向建模是一种将实际物体转换为数字模型的过程。通过逆向工程技术&#xff0c;可以将现有的灯具进行3D扫描&#xff0c;然后利用专业的逆向设计软件将其转换为准确的三维模型。 以下是CASAIM实施灯具三维逆向建模的一般步骤图&#xff1a; 1. 扫描&#xff1a;三维扫…...

Nginx反向代理-负载均衡、webshell实践

目录 1.nginx反向代理-负载均衡 1&#xff09;搭建web项目 2&#xff09;修改 nginx.conf的配置 2.webshell 实践 1&#xff09;异或操作绕过 2&#xff09;取反绕过 3&#xff09;php语法绕过 1.nginx反向代理-负载均衡 1&#xff09;搭建web项目 首先通过SpringBoo…...

第六阶|见道明心的笔墨(上)从书法之美到生活之美——林曦老师的线上直播书法课

如果你有需要&#xff0c;可以找我的&#xff0c;我这边有老师的所有课程 如果你有需要&#xff0c;可以找我的&#xff0c;我这边有老师的所有课程...

nbcio-boot从3.0升级到3.1的出现用户管理与数据字典bug

升级后出现 系统管理里的用户管理出现下面问题 2023-08-17 09:44:38.902 [http-nio-8080-exec-4] [1;31mERROR[0;39m [36mo.jeecg.common.exception.JeecgBootExceptionHandler:69[0;39m - java.lang.String cannot be cast to java.lang.Long java.lang.ClassCastException:…...

Curson 编辑器

Curson 汉化与vacode一样 Curson 自带chat功能 1、快捷键ctrlk(代码中编辑) 2、快捷键ctrll 右侧打开窗口...

Shell编程学习之函数的应用

Shell编程中的函数&#xff1a;伪代码表示&#xff1a; function 函数名(){函数体}注意事项&#xff1a; 1.函数无参数&#xff1b; 2.函数无返回值类型&#xff1b; 3.function可以不写&#xff1b; 4.函数不被调用&#xff0c;就不会执行&#xff1b; 5.函数名不能使用…...

Fork/Join框架

是什么 Fork/Join框架是Java 7提供的一个用于并行执行任务的框架&#xff0c;是一个把大任务分割成若干个小任务&#xff0c;最终汇总每个小任务结果后得到大任务结果的框架。 Fork: 把一个大任务切分为若干子任务并行的执行 Join: 合并这些子任务的执行结果&#xff0c;最后…...

LeetCode_字符串_中等_468.验证 IP 地址

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给定一个字符串 queryIP。如果是有效的 IPv4 地址&#xff0c;返回 “IPv4” &#xff1b;如果是有效的 IPv6 地址&#xff0c;返回 “IPv6” &#xff1b;如果不是上述类型的 IP 地址&#xff0c;返回 “Nei…...

ABAP Der Open SQL command is too big.

ABAP Der Open SQL command is too big. DBSQL_STMNT_TOO_LARGE CX_SY_OPEN_SQL_DB 应该是选择条件中 维护的条件值条数太多了...

QChart类用来 管理 图表的:数据序列(series)、图例(legend)和坐标轴(axis)

QChart类用来 管理 图表的&#xff1a;数据序列&#xff08;series&#xff09;、图例&#xff08;legend&#xff09;和坐标轴&#xff08;axis&#xff09; 1、数据序列类 继承关系 2、坐标轴类 的继承关系 3、图例类 什么是图例&#xff1f; 图例&#xff1a;是集中于地图…...

Servlet+JDBC实战开发书店项目讲解第10篇:在线客服功能实现

在线客服功能实现 实现思路 要实现在线客服功能&#xff0c;您可以考虑以下步骤&#xff1a; 创建一个用于存储客户消息和回复的数据库表。您可以使用JDBC连接到数据库&#xff0c;并使用SQL语句创建表格。 在您的Servlet中&#xff0c;创建一个用于处理客户消息和回复的POS…...

CVE-2023-21292 AMS框架层高危漏洞分析

文章目录 前言漏洞细节故事起源漏洞利用漏洞修复 总结 前言 本周在分析 Google 官方发布的 Android 2023 年8 月安全公告 涉及的漏洞补丁的时候&#xff0c;遇到一个有意思的漏洞&#xff1a;CVE-2023-21292。 之所以说它有意思是因为这个漏洞早在去年年底就在某平台上被国外…...

cuda、cuDNN、深度学习框架、pytorch、tentsorflow、keras这些概念之间的关系

当讨论CUDA、cuDNN、深度学习框架、pytorch、tensorflow、keras这些概念的时候&#xff0c;我们讨论的是与GPU加速深度学习相关的技术和工具。 CUDA&#xff08;Compute Unified Device Architecture&#xff09;&#xff1a; CUDA是由NVIDIA开发的一种并行计算平台和编程模型&…...

第二讲:BeanFactory的实现

BeanFactory的实现 1. 环境准备2. 初始化DefaultListableBeanFactory3. 手动注册BeanDefinition4. 手动添加后置处理器5. 获取被依赖注入的Bean对象6. 让所有的单例bean初始化时加载7. 总结 Spring 的发展历史较为悠久&#xff0c;因此很多资料还在讲解它较旧的实现&#xff0c…...

vue2+Spring Boot2.7 大文件分片上传

之前我们文章 手把手带大家实现 vue2Spring Boot2.7 文件上传功能 将了上传文件 但如果文件很大 就不太好处理了 按正常情况甚至因为超量而报错 这里 我弄了个足够大的文件 我们先搭建 Spring Boot2.7 环境 首先 application.yml 代码编写如下 server:port: 80 upload:path:…...

Vite更新依赖缓存失败,强制更新依赖缓存

使用vitets开发一段时间了&#xff0c;感觉并不是想象中的好用&#xff0c;特别是出现些稀奇古怪的问题不好解决&#xff0c;比如下面这个问题 上午9:50:08 [vite] error while updating dependencies: Error: ENOENT: no such file or directory, open E:/workspace-dir/node…...

Linux命令200例:tail用来显示文件的末尾内容(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…...

【Unity每日一记】进行发射,位置相关的方法总结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…...

MISRA 2012学习笔记(3)-Rules 8.4-8.7

文章目录 Rules8.4 字符集和词汇约定(Character sets and lexical conventions)Rule 4.1 八进制和十六进制转译序列应有明确的终止识别标识Rule 4.2 禁止使用三字母词(trigraphs) 8.5 标识符(Identifiers)Rule 5.1 外部标识符不得重名Rule 5.2 同范围和命名空间内的标识符不得重…...

centos7组件搭建

Linux&#xff08;包括centos&#xff09; 如何查看服务器内存、CPU su - root 切换用户 centos 密码 空格 https://blog.csdn.net/weixin_45277161/article/details/131524555 CentOS 7 安装 Docker 的详细步骤 https://blog.csdn.net/qq_39997939/article/details/13100…...

webpack5和webpack4的一些区别

自动清除打包目录 webpack4 // bash npm i clean-webpack-plugin -D //webpack.config.js const {CleanWebpackPlugin} require(clean-webpack-plugin); module.exports {plugins: [new CleanWebpackPlugin()} } webpack5 module.exports {output: {clean: true} } topLevel…...

攻防世界-fileclude

原题 解题思路 直接展示源码了&#xff0c;flag.php应该存放了flag&#xff0c;在file1与file2都不为空且file2是“hello ctf”时file1将被导入。接下来做法很明显&#xff0c;让file为flag.php&#xff0c;file2为“hello ctf”。“?file1php://filter/readconvert.base64-en…...

深度学习的“前世今生”

1、“感知机”的诞生 20世纪50年代&#xff0c;人工智能派生出了这样两个学派&#xff0c;分别是“符号学派”及“连接学派”。前者的领军学者有Marvin Minsky及John McCarthy&#xff0c;后者则是由Frank Rosenblatt所领导。 “符号学派”的人相信对机器从头编程&#xff0c…...

第一百一十九回 如何通过蓝牙设备读写数据

文章目录 概念介绍实现方法示例代码经验总结我们在上一章回中介绍了如何获取蓝牙状态相关的内容,本章回中将介绍 如何通过蓝牙设备读写数据。闲话休提,让我们一起Talk Flutter吧。 概念介绍 通过蓝牙设备读写数据有两种方法: 一种是读写Characteristics;一种是读写Descri…...

linux:Temporary failure in name resolutionCouldn’t resolve host

所有域名无法正常解析。 ping www.baidu.com 等域名提示 Temporary failure in name resolution错误。 rootlocalhost:~# ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolution rootlocalhost:~# 一、ubuntu/debian&#xff08;emporary failure i…...

C 语言的 sprintf() 函数

<stdio.h> 原型: int sprintf(char *str, const char *format, …) 发送格式化输出到 str 所指向的字符串。 参数 str – 这是指向一个字符数组的指针&#xff0c;该数组存储了 C 字符串。 format – 这是字符串&#xff0c;包含了要被写入到字符串 str 的文本。它…...

李沐pytorch学习-卷积网络及其实现

一、卷积概述 1.1 基本定义 卷积计算过程如图1所示&#xff0c;即输入矩阵和核函数&#xff08;filter&#xff09;对应的位置相乘&#xff0c;然后相加得到输出对应位置的数。 图1. 卷积计算过程 该过程可以形象地从图2中展现。 图2. 二维卷积示意图 1.2 实现互相关运算的代…...

记录:win10物理机ping不通虚拟机上的docker子网(已解决)

【说明】 windows10&#xff1a;已关闭防火墙 linux发行版本&#xff1a;centos7.9&#xff08;已禁用SElinux、已关闭防火墙&#xff09; 虚拟机软件&#xff1a;VMware Workstation 17 虚拟机网络模式&#xff1a;NAT模式 docker版本&#xff1a;20.4.5 docker网络模式…...

深入浅出Pytorch函数——torch.nn.init.kaiming_normal_

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 相关文章&#xff1a; 深入浅出Pytorch函数——torch.nn.init.calculate_gain 深入浅出Pytorch函数——torch.nn.init.uniform_ 深入浅出Pytorch函数——torch.nn.init.normal_ 深入浅出Pytorch函数——torch.nn.init.c…...

D. Anton and School - 2

范德蒙德恒等式 考虑统计每一个右括号位置的贡献&#xff0c;也就是每个右括号作为右边起点的贡献 其中i0的时候&#xff0c;r-1<r-0,故i0时贡献为0&#xff0c;直接套用恒等式不会有影响 #include <bits/stdc.h> using namespace std; typedef long long int ll; # d…...