知識點:一、使用多線程,多進程,協程完成web併發服務器 二、單進程-單線程-非堵塞也能夠實現併發服務器html
一、多進程和協程的代碼在下面註釋掉的部分,我把三種寫在一塊兒了web
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() # 一、多進程實現併發服務 # p = multiprocessing.Process(target=web_server, args=(new_socket,)) # p.start() # 二、協程實現併發服務 # p = gevent.spawn(web_server, new_socket) # p.start() # 三、多線程實現併發服務 t = threading.Thread(target=web_server, args=(new_socket,)) t.start() t.join() new_socket.close() tcp_socket.close() # 關閉監聽套接字
if __name__ == '__main__':
main()
運行效果:
瀏覽器訪問本地,會顯示一個界面,並且能夠開多個瀏覽器一塊兒運行
二、單進程-單線程-非堵塞也能夠實現併發服務器瀏覽器
"""利用單進程-單線程-非堵塞也能夠實現web併發服務(即不用多線程,多進程,協程) 思路:一、設置套接字爲非堵塞 二、在接收客戶端處:由於是非堵塞,因此要捕捉異常,當有客戶端進來,新客戶端的套接字也要設置非堵塞 還須要判斷接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()