python3 web服务器_python3 简单web服务器

补充:tcp长连接和短连接

长连接:

客户端向服务器发起连接请求,服务器接收到请求回应给客户端,双方完成三次握手,然后客户端发送消息,服务端回应消息,每一次完成读写操作,套接字不不关闭,也就是连接不关闭,继续保持连接,等待下一次的读写操作,长时间之后客户端发起关闭请求。

短连接:

短连接则是一般只会在 client/server 间传递一次读写操作,一次读写操作之后就关闭连接,下一次的操通信则又从三次握手开始重新建立连接。

简单的http服务器:

__author__ = 'Administrator'

importsocketdefservice_client(new_socket):#1.接收浏览器发送过来的请求,即http请求

request=new_socket.recv(1024)#2.返回浏览器http格式的数据

#2.1准备发送给浏览器的数据——header

#\r\n给Windows使用

response="HTTP/1.1 200 OK\r\n"response+="\r\n"

#2.2准备发送给浏览器的数据——body

response+="

哈哈哈哈哈

"new_socket.send(response.encode("utf-8"))#3.关闭套接字

new_socket.close()defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)#4.等待新客户端的链接

whileTrue:

new_socket,client_addr=tcp_server.accept()#5.为这个客户端服务

service_client(new_socket)#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

返回给浏览器相应的页面:

Python splitlines() 按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。

str.splitlines([keepends])

keepends -- 在输出结果里是否保留换行符('\r', '\r\n', \n'),默认为 False,不包含换行符,如果为 True,则保留换行符。

__author__ = 'Administrator'

importsocketdefservice_client(new_socket):#1.接收浏览器发送过来的请求,即http请求

request=new_socket.recv(1024)print("===="*100)print(request)#2.返回浏览器http格式的数据

#2.1准备发送给浏览器的数据——header

#\r\n给Windows使用

response="HTTP/1.1 200 OK\r\n"response+="\r\n"

#2.2准备发送给浏览器的数据——body

f=open("./html/index.html","rb")

html_content=f.read()

f.close()#将response header发送给浏览器

new_socket.send(response.encode("utf-8"))#将response body发送给浏览器

new_socket.send(html_content)#3.关闭套接字

new_socket.close()defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)#4.等待新客户端的链接

whileTrue:

new_socket,client_addr=tcp_server.accept()#5.为这个客户端服务

service_client(new_socket)#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

根据用户需求返回相应的页面(对页面进行操作之后返回的页面):

__author__ = 'Administrator'

importsocketimportredefservice_client(new_socket):#1.接收浏览器发送过来的请求,即http请求

request=new_socket.recv(1024).decode("utf-8")#print("===="*100)

#print(request)

request_lines =request.splitlines()print("")print(">>>>"*20)print(request_lines)#GET /index.html HTTP/1.1

file_name=""res=re.match(r"[^/]+(/[^ ]*)",request_lines[0])ifres:

file_name=res.group(1)if file_name=="/":

file_name="/index.html"

#2.返回浏览器http格式的数据

#\r\n给Windows使用

try:#忘了,复习一下

#try中是尝试执行的代码

#except 中是对错误进行处理

#else中是没有异常才会执行的代码

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="HTTP/1.1 200 OK\r\n"response+="\r\n"

#将response header发送给浏览器

new_socket.send(response.encode("utf-8"))#将response body发送给浏览器

new_socket.send(html_content)#3.关闭套接字

new_socket.close()defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)#4.等待新客户端的链接

whileTrue:

new_socket,client_addr=tcp_server.accept()#5.为这个客户端服务

service_client(new_socket)#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

使用多进程完成http服务器:

__author__ = 'Administrator'

importsocketimportreimportmultiprocessingdefservice_client(new_socket):#1.接收浏览器发送过来的请求,即http请求

request=new_socket.recv(1024).decode("utf-8")#print("===="*100)

#print(request)

request_lines =request.splitlines()print("")print(">>>>"*20)print(request_lines)#GET /index.html HTTP/1.1

file_name=""res=re.match(r"[^/]+(/[^ ]*)",request_lines[0])ifres:

file_name=res.group(1)if file_name=="/":

file_name="/index.html"

#2.返回浏览器http格式的数据

#\r\n给Windows使用

try:#忘了,复习一下

#try中是尝试执行的代码

#except 中是对错误进行处理

#else中是没有异常才会执行的代码

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="HTTP/1.1 200 OK\r\n"response+="\r\n"

#将response header发送给浏览器

new_socket.send(response.encode("utf-8"))#将response body发送给浏览器

new_socket.send(html_content)#3.关闭套接字

new_socket.close()defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)whileTrue:#4.等待新客户端的链接[这里类似银行的柜台窗口]

new_socket,client_addr=tcp_server.accept()#5.为这个客户端服务

p=multiprocessing.Process(target=service_client,args=(new_socket,))

p.start()#在主进程创建子进程之后,子进程会复制主进程的所有资源,所有就会有两个相同的new_socket套接字

#在service_client()中是子进程关闭了套接字,那在主进程中也是需要关闭该套接字

new_socket.close()#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

使用多线程完成http服务器:

__author__ = 'Administrator'

importsocketimportreimportthreadingdefservice_client(new_socket):#1.接收浏览器发送过来的请求,即http请求

request=new_socket.recv(1024).decode("utf-8")#print("===="*100)

#print(request)

request_lines =request.splitlines()print("")print(">>>>"*20)print(request_lines)#GET /index.html HTTP/1.1

file_name=""res=re.match(r"[^/]+(/[^ ]*)",request_lines[0])ifres:

file_name=res.group(1)if file_name=="/":

file_name="/index.html"

#2.返回浏览器http格式的数据

#\r\n给Windows使用

try:#忘了,复习一下

#try中是尝试执行的代码

#except 中是对错误进行处理

#else中是没有异常才会执行的代码

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="HTTP/1.1 200 OK\r\n"response+="\r\n"

#将response header发送给浏览器

new_socket.send(response.encode("utf-8"))#将response body发送给浏览器

new_socket.send(html_content)#3.关闭套接字

new_socket.close()defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)whileTrue:#4.等待新客户端的链接

new_socket,client_addr=tcp_server.accept()#5.为这个客户端服务

p=threading.Thread(target=service_client,args=(new_socket,))

p.start()#注意:这里和进程的区别,多线程之间共享变量,子线程没有复制主线程

#new_socket.close()

#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

使用gevent(协程)完成http服务器:

__author__ = 'Administrator'

importsocketimportreimportgeventfrom gevent importmonkey

monkey.patch_all()defservice_client(new_socket):#1.接收浏览器发送过来的请求,即http请求

request=new_socket.recv(1024).decode("utf-8")#print("===="*100)

#print(request)

request_lines =request.splitlines()print("")print(">>>>"*20)print(request_lines)#GET /index.html HTTP/1.1

file_name=""res=re.match(r"[^/]+(/[^ ]*)",request_lines[0])ifres:

file_name=res.group(1)if file_name=="/":

file_name="/index.html"

#2.返回浏览器http格式的数据

#\r\n给Windows使用

try:#忘了,复习一下

#try中是尝试执行的代码

#except 中是对错误进行处理

#else中是没有异常才会执行的代码

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="HTTP/1.1 200 OK\r\n"response+="\r\n"

#将response header发送给浏览器

new_socket.send(response.encode("utf-8"))#将response body发送给浏览器

new_socket.send(html_content)#3.关闭套接字

new_socket.close()defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)whileTrue:#4.等待新客户端的链接

new_socket,client_addr=tcp_server.accept()#5.为这个客户端服务

gevent.spawn(service_client,new_socket)#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

单进程、线程、非堵塞实现并发:

__author__ = 'Administrator'

importsocket

tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

tcp_socket.bind(("",8081))

tcp_socket.listen(128)#设置套接字为非堵塞方式

tcp_socket.setblocking(False)

client_list=list()#在没有设置套接字为堵塞的时候,accept和recv默认都是堵塞的,那客户端没有发送链接或者没有发送数据过来都是不会报异常的,#现在设置套接字为非堵塞,那么此时accept就是非堵塞的,那客户端没有发送链接或者没有发送数据过来都是报异常的,

whileTrue:try:

new_tcp_socket,addr=tcp_socket.accept()exceptException as res:print(res)print("————没有新的客户端链接————")else:#设置新的套接字为非堵塞,默认堵塞的时候,不发数据过来不会异常,但是此时非堵塞不发数据过来就会异常

new_tcp_socket.setblocking(False)

client_list.append(new_tcp_socket)for client_socket inclient_list:try:

recv_data=new_tcp_socket.recv(1024)exceptException as res:print(res)print("————客户端没有发送数据过来————")else:print(recv_data)ifrecv_data:print("————客户端发送数据过来————")else:

client_list.remove(new_tcp_socket)

new_tcp_socket.close()print("————客户端已经关闭了————")

View Code

单进程、线程、非堵塞、长连接实现http服务器:

__author__ = 'Administrator'

importsocketimportredefservice_client(new_socket,request):#1.接收浏览器发送过来的请求,即http请求

#request=new_socket.recv(1024).decode("utf-8")

#print("===="*100)

#print(request)

request_lines =request.splitlines()print("")print(">>>>"*20)print(request_lines)#GET /index.html HTTP/1.1

file_name=""res=re.match(r"[^/]+(/[^ ]*)",request_lines[0])ifres:

file_name=res.group(1)if file_name=="/":

file_name="/index.html"

#2.返回浏览器http格式的数据

#\r\n给Windows使用

try:#忘了,复习一下

#try中是尝试执行的代码

#except 中是对错误进行处理

#else中是没有异常才会执行的代码

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_content

response_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_body#将response 发送给浏览器

new_socket.send(response)#3.关闭套接字

#在这个地方服务器强制关闭了套接字,表明了并不是长连接,而是短连接

#new_socket.close()

defmain():#1.创建套接字

tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#2.绑定

tcp_server.bind(("",8081))#3.监听套接字

tcp_server.listen(128)

tcp_server.setblocking(False)#将套接字设置为非堵塞

client_list=list()#4.等待新客户端的链接

whileTrue:try:

new_socket,client_addr=tcp_server.accept()exceptException as res:pass

else:

new_socket.setblocking(False)

client_list.append(new_socket)for client_socket inclient_list:try:

recv_data= client_socket.recv(1024).decode("utf-8")exceptException as res:pass

else:ifrecv_data:

service_client(client_socket,recv_data)else:

client_socket.close()

client_list.remove(client_socket)#6.关闭监听套接字

tcp_server.close()if __name__ == '__main__':

main()

View Code

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发链接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。

通信过程:

浏览器访问服务器的过程

在浏览器访问http:www.baidu.com(域名),该电脑先检查是否认识默认网关的MAC地址,如果没有以arp广播,

广播过去该电脑的默认网关地址组织一个域名解析的数据请求发送给网关,网关发送到互联网上,互联网经过一层一层的转发,

到达DNS服务器,其把域名解析出来之后把ip地址回送给浏览器,然后把ip发送给网关,网关把数据发送到互联网,把数据转发给服务器,

发送到服务器,客户端和浏览器三次握手成功,浏览器把请求发送给服务器,服务器解析请求返回数据给客户端,

浏览器显示,显示成功之后,然后四次挥手,结束。

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

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

相关文章

零基础学C语言必备书籍,抖音编程达人推荐(进群交流学习互动)

C语言从入门到进阶的书籍推荐。 【基础】 这本谭浩强写的【C语言程序设计】可谓是广大人事的入门书籍。我曾经用的教材就是这本,里面大概涵盖了 C语言 语法的 80% 。一个很适合自学的入门书。 【c prime puls】 是 C语言 最经典的入门书籍,极力推荐。每…

网站如何进行渠道跟踪_网站如何进行搜索引擎优化?

这是一个很一般的平台标题,没有任何吸引力,但是它真的可以被一个很好的基层站长估计的很少,我问一个做了多年基层站长的朋友,我说如何做好搜索引擎优化的SEO,他给我的答案很难,答案太大了,所以我…

axure 图片切换图片的交互_AxureRP8中实现伸缩式的图片展示交互效果

上午的时候,在一个群里看到这样的实现需求。伸伸缩缩,感觉很爽的样子。那么,这样的一个交互效果如何实现呢?详细的教程我就不写了,直接上交互截图和源文件就好了。好多操作步骤是吧?实际上,只需…

什么是编程语言,大神教你为什么要学C语言?

首先来说说编程语言这个概念。 编程,其实就是让计算机听懂自己的话,让计算机帮自己想干的事情。编程语言,就是让你能够和计算机进行交流的一种语言。说白了就是让你的软件按你的命令干活。 打比方说,我们经常在僵尸片里面看到&a…

xshell vim 不能粘贴_linux基础知识:vim(vi)的知识

### vim三种模式命令行模式:在该模式下不能对文本进行- 直接编辑,可以输入一些操作(删除行,复制行,移动光标,粘贴)【打开之后默认进入的模式】编辑模式:在该模式下可以对文件内容进行编辑末行模式&#xff…

新手如何学习C语言/C++,教你一年时间是拿到年薪50万

最近会有一些初中高中大学的同学问,C语言C不知道怎么学习不会写代码怎么办?大致上都是一些类似的问题吧,回想一下自己走过的路,反复的了很久思考然后写了这篇文章,希望可以对一些迷惘新手小白程序员同学一丝帮助&#…

html横线标记_html中横线怎么写代码

html代码中:如何输入一条长长的横线呀? 用input页面标签 并将下Border设为直线 input[type="text"]{border-bottom:solid 1px #ccc;} html代码中:如何输入一条长长的横线? 你可以用div标签去实现: 横线中间有字 【html5与html的区别】 html通常指的是用来写网页的…

pycharm导入模块不智能显示_Pycharm自动导入模块小技巧

原标题:Pycharm自动导入模块小技巧作者 | 刘志军来源 | Python之禅如果能把工具熟练运用,往往能达到事半功倍的效果,Pycharm 是很多Python开发者的首选IDE,提供各种快捷键、重构功能、调试技巧等,Python是动态语言&…

mac adb 找不到设备_win/Mac办公软件下载找不到资源?试试这三个强大的神器

大家好,我们在办公时,office、wps等办公软件是我们必须用到的,还有一些专业软件:CAD、PS、PROE、UG、SolidWorks、keyshot、VRay、3DsMax、Labview、Maya、AE、AI、ANSYS等也是各行各业的专业人员工作时必不可少的,但是…

C语言入门经验:零基础如何学习C语言?

工作中,接触过很多想到学习c语言而又没有一点计算机基础的人。经常有人问”我没有一点基础,该怎么入门c语言啊”。看过很多初学者久久摸不到门路,每到这个时候,脑海中总会浮现一个问题:学习c语言真的就那么难吗? 不难…

手机1像素线粗_关于移动端一像素线的解决方案

为什么会有一像素线这个问题因为移动端布局我们大家都知道根据不同的手机会有不同的dpr 例如 爱疯6plus就是3 爱疯6就是2 当我们定义1px的时候就会在不同手机里面显示不同的粗细长度,dpr为3的时候就是3px,dpr为2的时候就是2px,具体dpr是什么…

20天掌握C语言,C语言零基础到项目实战,玩转C语言

一般来说,和其他编程语言相比,C/C语言学起来会比较累,如果想达到项目开发的状态,更是需要花费很长时间的努力。那么,如何才能更好地把所学知识用到实际工作中去呢?今天小编就带大家来看看学习C/C语言到什么…

32岁了学python来的及吗_现在27岁学python来得及吗?

答案是肯定的,27岁学习Python语言是来得及的。 学习Python语言是当前一个比较好的选择,原因有以下几点: 第一,Python语言有健全的生态。Python语言虽然在最近几年被广泛关注,但是Python语言并不是一个新出现的语言&…

怎样快速画出一个正方体_小学数学非常有效的“画图”解题法,快速解题的“金钥匙”...

小学阶段的数学主要培养的是孩子的逻辑思维能力,是从形象思维逐步过度到抽象思维的过程,如果在小学阶段没有将基础打牢,那么等孩子上初中后面对更复杂的学习内容,就会变得更吃力。在小学数学中,“画图”是帮助孩子建立…

零基础入门C语言,只需2小时轻松学会!

学好C语言的秘诀就是1234:“一字真言,两种态度,三个框架,四项注意”。 如有小伙伴想自学,可以进群731871503进行交流 学习,提升编程,共同进步 一、一字真言 各位看官,学好C语言&a…

python调用百度地图画轨迹图_[宜配屋]听图阁

如题,先上效果图:主要分为两大步骤 使用python语句,通过百度地图API,对已知的地名抓取经纬度 使用百度地图API官网的html例程,修改数据部分,实现呈现效果 一、使用python语句,通过百度地图API&a…

select 移动端 第一个无法选中_总结在移动端碰到的坑

一、安卓设备的select options的坑,尽量使用各浏览器内核都支持的api在添加 OPTION 元素时如果需要向指定索引前插入 OPTION,可以使用 options.add(option, index);如果需要向 SELECT 尾部添加 OPTION,可以使用 options.add(optio…

零基础初学c语言常见的10个错误

时光匆匆,新的学年又即将要来临。很多有意愿报我们学院的准学弟学妹们,都开始提前学习c语言这门功课。 如有小伙伴想自学,可以进群731871503进行交流学习,提升编程,共同进步 但是很多学弟学妹们之前都没有学习过太多相…

centos7安装yum_centos7下yum方式安装jenkins

一、首先安装java组件1、可以直接yum安装yum install -y java2、或者下载jdk的包,设置环境变量也是可以的https://download.oracle.com/otn/java/jdk/11.0.510/e51269e04165492b90fa15af5b4eb1a5/jdk-11.0.5_linux-x64_bin.tar.gz?AuthParam1578369202_107ade17483…

感知器及其在python中的实现_(二)感知器算法及其python实现

出发点一旦判别函数的形式确定下来,不管它是线性的还是非线性的,剩下的问题就是如何确定它的系数。在模式识别中,系数确定的一个主要方法就是通过对已知样本的训练和学习来得到。感知器算法就是通过训练样本模式的迭代和学习,产生…