web服务-2、四种方法实现并发服务器-多线程,多进程,协程,(单进程-单线程-非堵塞)
知识点:1、使用多线程,多进程,协程完成web并发服务器 2、单进程-单线程-非堵塞也可以实现并发服务器
1、多进程和协程的代码在下面注释掉的部分,我把三种写在一起了
import socket
import re
import threading
import multiprocessing
import gevent """服务器收发数据"""
def web_server(new_socket): datas = new_socket.recv(1024).decode('utf-8') # 接收浏览器请求的数据
print(datas)
data1 = datas.splitlines()
res = re.match("[^/]+(/[^ ]*)", data1[0]) # 使用正则获取到请求头部中的的第一行中的请求地址对象
if res: # 判断如果请求地址有内容
file_name = res.group(1) # 获取正则对象中的内容
if file_name == '/': # 如果地址是‘/’,也就是请求地址后面没有带指的页面,即主页
file_name = '/index.html'
try:
data = open('./html'+file_name,'rb') # 获取请求的资源在服务器中的文件
except:
data_body = 'HTTP 404 NOT FOUND/1.1\r\n' # 服务器发送消息的头部需要换行,用\r\n
data_body += '\r\n' # 头部和body需要空一行
data_body += '<h1>not found</h1>' # 服务器没找到浏览器需要的资源,返回的html页面
new_socket.send(data_body.encode('utf-8')) # 发送给浏览器
else:
data_head = 'HTTP 200 OK/1.1\r\n' # 请求成功,服务器返回200
data_head += '\r\n'
data_body = data.read()
data.close() # 关闭文件
new_socket.send(data_head.encode('utf-8'))
new_socket.send(data_body)
new_socket.close() # 关闭新的客户端套接字 """主程序入口"""
def main():
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 防止下一次使用该服务器端口被占用情况
tcp_socket.bind(('127.0.0.1', 7789)) # 服务器绑定地址和端口
tcp_socket.listen(128) # 监听套接字
while True:
new_socket, adrees = tcp_socket.accept()
# 1、多进程实现并发服务
# p = multiprocessing.Process(target=web_server, args=(new_socket,))
# p.start() # 2、协程实现并发服务
# p = gevent.spawn(web_server, new_socket)
# p.start() # 3、多线程实现并发服务
t = threading.Thread(target=web_server, args=(new_socket,))
t.start()
t.join()
new_socket.close()
tcp_socket.close() # 关闭监听套接字
if __name__ == '__main__':
main()
运行效果:
浏览器访问本地,会显示一个界面,而且可以开多个浏览器一起运行
2、单进程-单线程-非堵塞也可以实现并发服务器
"""利用单进程-单线程-非堵塞也可以实现web并发服务(即不用多线程,多进程,协程)
思路:1、设置套接字为非堵塞
2、在接收客户端处:因为是非堵塞,所以要捕捉异常,当有客户端进来,新客户端的套接字也要设置非堵塞
还需要判断接recv是否是有数据,没有数据说明客户端断开连接,关闭套接字 """ def main():
main_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
main_socket.bind(('127.0.0.1',7785))
main_socket.listen(128)
main_socket.setblocking(False)
socket_list = list()
while True:
time.sleep(1)
try:
new_socket,new_adress = main_socket.accept()
except:
print('没有客户端进来,请稍等.....')
else:
print('一个新的客户端进来了......')
new_socket.setblocking(False)
socket_list.append(new_socket)
for client in socket_list:
try:
recv_data = client.recv(1024).decode('utf-8')
except:
print('客户端没有发送过来数据')
else:
print('无异常')
if recv_data:
print('客户端发来了消息')
print(recv_data)
data1 = recv_data.splitlines()
res = re.match("[^/]+(/[^ ]*)", data1[0])
if res:
file_name = res.group(1)
print('--------------' + res.group(1))
if file_name == '/':
file_name = '/index.html'
try:
data = open('./html' + file_name, 'rb')
except:
data_body = 'HTTP 404 NOT FOUND/1.1\r\n'
data_body += '\r\n'
data_body += '<h1>not found</h1>'
client.send(data_body.encode('utf-8'))
else:
data_body = data.read()
data.close()
data_head = 'HTTP 200 OK/1.1\r\n'
data_head += 'Content-Length:%d\r\n' % len(data_body)
data_head += '\r\n'
reponse = (data_head.encode('utf-8')+data_body)
client.send(reponse)
else:
client.close()
socket_list.remove(client)
main_socket.close() if __name__ == '__main__':
main()
web服务-2、四种方法实现并发服务器-多线程,多进程,协程,(单进程-单线程-非堵塞)的更多相关文章
- web服务-3、epoll高效率实现并发服务器
知识点: 之前写的四种方法实现并发服务效率都还是低,早期的服务器采用的是select和poll方式,select这种方式的特点是轮询所有套接字去一个个看有没有事件发生,但是装套接字的列表长度是有限制的 ...
- Python并发编程——多线程与协程
Pythpn并发编程--多线程与协程 目录 Pythpn并发编程--多线程与协程 1. 进程与线程 1.1 概念上 1.2 多进程与多线程--同时执行多个任务 2. 并发和并行 3. Python多线 ...
- Tomcat中部署WEB项目的四种方法
对Tomcat部署web应用的方式总结,常见的有以下四种: 1.[使用控制台部署] 访问Http://localhost:8080,并通过Tomcat Manager登录,进入部署界面即可. 2.[利 ...
- [Web 前端] 018 css 清除浮动的四种方法
清除浮动的四种方法 加 clear: ...(见例1) 父级上增加属性 overflow:hidden(见例2.1) 在最后一个子元素的后面加一个空的 div,给它一个样式属性 clear: both ...
- Tomcat系列(11)——Tomcat 部署web应用的4种方法
核心内容 1.在Tomcat中有四种部署Web应用的方式,分别是: (1)利用Tomcat自动部署(项目直接拷贝OR WAR包拷贝 到webapps下) (2)利用控制台进行部署(tomcat的man ...
- 使用Spring Security3的四种方法概述
使用Spring Security3的四种方法概述 那么在Spring Security3的使用中,有4种方法: 一种是全部利用配置文件,将用户.权限.资源(url)硬编码在xml文件中,已经实现过, ...
- Springboot 优雅停止服务的几种方法
在使用Springboot的时候,都要涉及到服务的停止和启动,当我们停止服务的时候,很多时候大家都是kill -9 直接把程序进程杀掉,这样程序不会执行优雅的关闭.而且一些没有执行完的程序就会直接退出 ...
- ASP.NET 使用 Dispose 释放资源的四种方法
Dispose 和 Finalize 是运行的 .NET 和 .NET Core 应用程序释放占用的资源的两种方法.通常,如果应用程序中有非托管资源,应该显式地释放这些资源占用的资源. 由于 Fina ...
- linux下配置ip地址四种方法(图文方法)
主要是用第四种方法 (1)Ifconfig命令 第一种使用ifconfig命令配置网卡的ip地址.此命令通常用来零时的测试用,计算机启动后 ip地址的配置将自动失效.具体用法如下.Ipconfig ...
随机推荐
- 一种使用 sprintf 导致死机的情况
@2019-02-26 [小记] char temp[10] float money; sprintf(temp, "0.2f", money); 以上使用方法可能导致死机,原因是 ...
- Markdown初入门(使用Typora编辑)
标题 使用#来实现标题的大小控制 # h1 标题1 ## h2 标题2 ### h3 标题3 #### h4 标题4 ##### h5 标题5 ###### h6 标题6 标题一 标题二 标题三 标题 ...
- django restframework 跨域访问
场景介绍: 在Django开发过程中,使用前后端分离设计的站点越来越多,如Django+VUE.Django+Angular.在使用DjangoRestFramework开发API的过程中,由于前端站 ...
- 消息框MessageBox+遍历控件
消息对话框:主要用来显示信息,也可以警告.用户确认取消等. MessageBox.Show("展示内容","标题",MessageBoxButtons.按钮种类 ...
- org.hibernate.ObjectNotFoundException: No row with the given identifier exists解决办法
hibernate-取消关联外键引用数据丢失抛异常的设置@NotFound hibernate项目里面配了很多many-to-one的关联,后台在查询数据时已经作了健全性判断,但还是经常抛出对象找不到 ...
- ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)
https://nanti.jisuanke.com/t/31454 题意 两个人玩游戏,最初数字为m,有n轮,每轮三个操作给出a b c,a>0表示可以让当前数字加上a,b>0表示可以让 ...
- SpringBoot系列: 如何优雅停止服务
============================背景============================在系统生命周期中, 免不了要做升级部署, 对于关键服务, 我们应该能做到不停服务完成 ...
- 使用/dev/poll的str_cli函数
void str_cli(FILE *fp, int sockfd) { int stdineof; char buf[MAXLINE]; int n; int wfd; ]; struct dvpo ...
- Coursera, Big Data 3, Integration and Processing (week 5)
Week 5, Big Data Analytics using Spark Programing in Spark Spark Core: Programming in Spark us ...
- Ansible------角色
什么是角色 角色是一种解决问题的思想,也是一种规范. 目录 角色的目录结构如下: files: 存放由copy或script模块等调用的文件. templates: template模块查找所需要模板 ...