一葡粒、49_按需返回頁(yè)面的http服務(wù)器
"""
http(超文本傳輸)協(xié)議: 基于Tcp
Tcp類似于2人通話可以接收到(穩(wěn)定);
Cdp類似于廣播, 有可能接收不到
"""
"""根據(jù)用戶的需求返回相應(yīng)的頁(yè)面"""
import socket
import re
def service_client(new_socket):
"""為客戶端返回?cái)?shù)據(jù)"""
? ? # 1漩怎、接收瀏覽器發(fā)送過(guò)來(lái)的請(qǐng)求, 即http請(qǐng)求
# -->例GET /index.html HTTP/1.1 .....
# http://127.0.0.1:7890/
# http://127.0.0.1:7890/index.html
? ? requst = new_socket.recv(1024).decode("utf-8")
"""【.decode:解碼】"""
? ? # print("-*-" * 20)
# print(requst)
? ? requst_lines = requst.splitlines()
print("")
print("-*-" *20)
print(requst_lines)
# GET / HTTP/1.1
# GET /index.html HTTP/1.1
# get post put del.....
? ? ret = re.match(r"[^/]+/([^ ]*)", requst_lines[0])
file_name =""
? ? if ret:
file_name = ret.group(1)
print("*" *50, file_name)
if file_name =="/":
file_name ='/inedx.html'
? ? # 2、返回http格式的數(shù)據(jù)給瀏覽器
? ? try:
# f = open("../buickmall/indexhtml", "rb")
? ? ? ? f =open("../buickmall" + file_name, "rb")
"""【rb:二進(jìn)制讀】"""
? ? except:
response ="HTTP/1.1 404 NOT FOUND\r\n"
? ? ? ? response +="\r\n"
? ? ? ? response +="---file not found---"
? ? ? ? new_socket.send(response.encode("utf-8"))
"""如果網(wǎng)址或(進(jìn)程)出錯(cuò)時(shí)該給用戶顯示什么"""
? ? else:
html_coutent = f.read()
f.close()
# 2.1 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Header
? ? ? ? response ="HTTP/1.1 200 OK\r\n"
? ? ? ? response +="\r\n"
? ? ? ? """【\r\n: 換行(兼容所有的瀏覽器)】"""
? ? ? ? # 2.2 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Body
# response += "
hehehe
"
# 將Response Header發(fā)送給瀏覽器
? ? ? ? new_socket.send(response.encode("utf-8"))
"""【send: 發(fā)送【encode: 編碼】"""
? ? ? ? # 將Response Body發(fā)送給瀏覽器
? ? ? ? new_socket.send(html_coutent)
# 關(guān)閉套接字
? ? new_socket.close()
def main():
"""用來(lái)整體控制"""
? ? # 1、創(chuàng)建套接字
? ? tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
"""選擇讓服務(wù)端先關(guān)閉"""
? ? # 2谁鳍、綁定; 參數(shù)("任意服務(wù)端ip", 端口)
? ? tcp_server_socket.bind(("", 7890))
# 3、變?yōu)楸O(jiān)聽(tīng)的套接字; 【listen:最大鏈接數(shù)】
? ? tcp_server_socket.listen(128)
while True:
# 4轩性、等待新客戶端的連接; 變量[新客戶端的套接字, 客戶端的IP和媳、端口]
? ? ? ? new_socket, client_addr = tcp_server_socket.accept()
# 5格遭、為這個(gè)客戶端服務(wù)
? ? ? ? service_client(new_socket)
# 6、關(guān)閉監(jiān)聽(tīng)套接字
? ? tcp_server_socket.close(new_socket)
if __name__ =='__main__':
main()
二留瞳、50_http協(xié)議復(fù)習(xí)
請(qǐng)求和響應(yīng)都會(huì)分頭和體
三拒迅、51_多進(jìn)程服務(wù)器
"""使用多進(jìn)程完成http服務(wù)器"""
import multiprocessing
"""導(dǎo)入多進(jìn)程包"""
import socket
import re
"""線程間共享全局變量; 進(jìn)程間不共享"""
def service_client(new_socket):
"""為客戶端返回?cái)?shù)據(jù)"""
? ? # 1、接收瀏覽器發(fā)送過(guò)來(lái)的請(qǐng)求, 即http請(qǐng)求
# -->例GET /index.html HTTP/1.1 .....
# http://127.0.0.1:7890/
# http://127.0.0.1:7890/index.html
? ? requst = new_socket.recv(1024).decode("utf-8")
"""【.decode:解碼】"""
? ? # print("-*-" * 20)
# print(requst)
? ? requst_lines = requst.splitlines()
print("")
print("-*-" *20)
print(requst_lines)
# GET / HTTP/1.1
# GET /index.html HTTP/1.1
# get post put del.....
? ? ret = re.match(r"[^/]+/([^ ]*)", requst_lines[0])
file_name =""
? ? if ret:
file_name = ret.group(1)
print("*" *50, file_name)
if file_name =="/":
file_name ='/inedx.html'
? ? # 2撼港、返回http格式的數(shù)據(jù)給瀏覽器
? ? try:
# f = open("../buickmall/indexhtml", "rb")
? ? ? ? f =open("../buickmall" + file_name, "rb")
"""【rb:二進(jìn)制讀】"""
? ? except:
response ="HTTP/1.1 404 NOT FOUND\r\n"
? ? ? ? response +="\r\n"
? ? ? ? response +="---file not found---"
? ? ? ? new_socket.send(response.encode("utf-8"))
"""如果網(wǎng)址或(進(jìn)程)出錯(cuò)時(shí)該給用戶顯示什么"""
? ? else:
html_coutent = f.read()
f.close()
# 2.1 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Header
? ? ? ? response ="HTTP/1.1 200 OK\r\n"
? ? ? ? response +="\r\n"
? ? ? ? """【\r\n: 換行(兼容所有的瀏覽器)】"""
? ? ? ? # 2.2 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Body
# response += "
hehehe
"
# 將Response Header發(fā)送給瀏覽器
? ? ? ? new_socket.send(response.encode("utf-8"))
"""【send: 發(fā)送【encode: 編碼】"""
? ? ? ? # 將Response Body發(fā)送給瀏覽器
? ? ? ? new_socket.send(html_coutent)
# 關(guān)閉套接字
? ? new_socket.close()
def main():
"""用來(lái)整體控制"""
? ? # 1坪它、創(chuàng)建套接字
? ? tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
"""選擇讓服務(wù)端先關(guān)閉"""
? ? # 2、綁定; 參數(shù)("任意服務(wù)端ip", 端口)
? ? tcp_server_socket.bind(("", 7890))
# 3帝牡、變?yōu)楸O(jiān)聽(tīng)的套接字; 【listen:最大鏈接數(shù)】
? ? tcp_server_socket.listen(128)
while True:
# 4往毡、等待新客戶端的連接; 變量[新客戶端的套接字, 客戶端的IP、端口]
? ? ? ? new_socket, client_addr = tcp_server_socket.accept()
# 5靶溜、為這個(gè)客戶端服務(wù)
? ? ? ? p = multiprocessing.process(target=service_client, args=(new_socket,))
"""作用: 創(chuàng)建一個(gè)子進(jìn)程【args里面的是元組, 所以要加一個(gè)逗號(hào)"""
? ? ? ? p.start()
new_socket.close()
# 6开瞭、關(guān)閉監(jiān)聽(tīng)套接字
? ? tcp_server_socket.close(new_socket)
if __name__ =='__main__':
main()
四、52_多線程服務(wù)器
"""使用多線程完成http服務(wù)器"""
import threading
"""導(dǎo)入線程包"""
import socket
import re
"""線程間共享全局變量; 進(jìn)程間不共享"""
def service_client(new_socket):
"""為客戶端返回?cái)?shù)據(jù)"""
? ? # 1罩息、接收瀏覽器發(fā)送過(guò)來(lái)的請(qǐng)求, 即http請(qǐng)求
# -->例GET /index.html HTTP/1.1 .....
# http://127.0.0.1:7890/
# http://127.0.0.1:7890/index.html
? ? requst = new_socket.recv(1024).decode("utf-8")
"""【.decode:解碼】"""
? ? # print("-*-" * 20)
# print(requst)
? ? requst_lines = requst.splitlines()
print("")
print("-*-" *20)
print(requst_lines)
# GET / HTTP/1.1
# GET /index.html HTTP/1.1
# get post put del.....
? ? ret = re.match(r"[^/]+/([^ ]*)", requst_lines[0])
file_name =""
? ? if ret:
file_name = ret.group(1)
print("*" *50, file_name)
if file_name =="/":
file_name ='/inedx.html'
? ? # 2嗤详、返回http格式的數(shù)據(jù)給瀏覽器
? ? try:
# f = open("../buickmall/indexhtml", "rb")
? ? ? ? f =open("../buickmall" + file_name, "rb")
"""【rb:二進(jìn)制讀】"""
? ? except:
response ="HTTP/1.1 404 NOT FOUND\r\n"
? ? ? ? response +="\r\n"
? ? ? ? response +="---file not found---"
? ? ? ? new_socket.send(response.encode("utf-8"))
"""如果網(wǎng)址或(進(jìn)程)出錯(cuò)時(shí)該給用戶顯示什么"""
? ? else:
html_coutent = f.read()
f.close()
# 2.1 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Header
? ? ? ? response ="HTTP/1.1 200 OK\r\n"
? ? ? ? response +="\r\n"
? ? ? ? """【\r\n: 換行(兼容所有的瀏覽器)】"""
? ? ? ? # 2.2 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Body
# response += "
hehehe
"
# 將Response Header發(fā)送給瀏覽器
? ? ? ? new_socket.send(response.encode("utf-8"))
"""【send: 發(fā)送【encode: 編碼】"""
? ? ? ? # 將Response Body發(fā)送給瀏覽器
? ? ? ? new_socket.send(html_coutent)
# 關(guān)閉套接字
? ? new_socket.close()
def main():
"""用來(lái)整體控制"""
? ? # 1、創(chuàng)建套接字
? ? tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
"""選擇讓服務(wù)端先關(guān)閉"""
? ? # 2瓷炮、綁定; 參數(shù)("任意服務(wù)端ip", 端口)
? ? tcp_server_socket.bind(("", 7890))
# 3葱色、變?yōu)楸O(jiān)聽(tīng)的套接字; 【listen:最大鏈接數(shù)】
? ? tcp_server_socket.listen(128)
while True:
# 4、等待新客戶端的連接; 變量[新客戶端的套接字, 客戶端的IP娘香、端口]
? ? ? ? new_socket, client_addr = tcp_server_socket.accept()
# 5苍狰、為這個(gè)客戶端服務(wù)
? ? ? ? p = threading.Thread(target=service_client, args=(new_socket,))
"""作用: 創(chuàng)建一個(gè)子進(jìn)程【args里面的是元組, 所以要加一個(gè)逗號(hào)"""
? ? ? ? p.start()
# new_socket.close()
# 6办龄、關(guān)閉監(jiān)聽(tīng)套接字
? ? tcp_server_socket.close(new_socket)
if __name__ =='__main__':
main()
五、53_協(xié)程服務(wù)器
"""使用gevent來(lái)實(shí)現(xiàn)http服務(wù)器"""
import gevent
from geventimport monkey
monkey.patch_all()
"""導(dǎo)入?yún)f(xié)程包等資源"""
import socket
import re
"""線程間共享全局變量; 進(jìn)程間不共享"""
def service_client(new_socket):
"""為客戶端返回?cái)?shù)據(jù)"""
? ? # 1淋昭、接收瀏覽器發(fā)送過(guò)來(lái)的請(qǐng)求, 即http請(qǐng)求
# -->例GET /index.html HTTP/1.1 .....
# http://127.0.0.1:7890/
# http://127.0.0.1:7890/index.html
? ? requst = new_socket.recv(1024).decode("utf-8")
"""【.decode:解碼】"""
? ? # print("-*-" * 20)
# print(requst)
? ? requst_lines = requst.splitlines()
print("")
print("-*-" *20)
print(requst_lines)
# GET / HTTP/1.1
# GET /index.html HTTP/1.1
# get post put del.....
? ? ret = re.match(r"[^/]+/([^ ]*)", requst_lines[0])
file_name =""
? ? if ret:
file_name = ret.group(1)
print("*" *50, file_name)
if file_name =="/":
file_name ='/inedx.html'
? ? # 2俐填、返回http格式的數(shù)據(jù)給瀏覽器
? ? try:
# f = open("../buickmall/indexhtml", "rb")
? ? ? ? f =open("../buickmall" + file_name, "rb")
"""【rb:二進(jìn)制讀】"""
? ? except:
response ="HTTP/1.1 404 NOT FOUND\r\n"
? ? ? ? response +="\r\n"
? ? ? ? response +="---file not found---"
? ? ? ? new_socket.send(response.encode("utf-8"))
"""如果網(wǎng)址或(進(jìn)程)出錯(cuò)時(shí)該給用戶顯示什么"""
? ? else:
html_coutent = f.read()
f.close()
# 2.1 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Header
? ? ? ? response ="HTTP/1.1 200 OK\r\n"
? ? ? ? response +="\r\n"
? ? ? ? """【\r\n: 換行(兼容所有的瀏覽器)】"""
? ? ? ? # 2.2 準(zhǔn)備給瀏覽器發(fā)送的數(shù)據(jù) :Body
# response += "
hehehe
"
# 將Response Header發(fā)送給瀏覽器
? ? ? ? new_socket.send(response.encode("utf-8"))
"""【send: 發(fā)送【encode: 編碼】"""
? ? ? ? # 將Response Body發(fā)送給瀏覽器
? ? ? ? new_socket.send(html_coutent)
# 關(guān)閉套接字
? ? new_socket.close()
def main():
"""用來(lái)整體控制"""
? ? # 1、創(chuàng)建套接字
? ? tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
"""選擇讓服務(wù)端先關(guān)閉"""
? ? # 2翔忽、綁定; 參數(shù)("任意服務(wù)端ip", 端口)
? ? tcp_server_socket.bind(("", 7890))
# 3英融、變?yōu)楸O(jiān)聽(tīng)的套接字; 【listen:最大鏈接數(shù)】
? ? tcp_server_socket.listen(128)
while True:
# 4、等待新客戶端的連接; 變量[新客戶端的套接字, 客戶端的IP歇式、端口]
? ? ? ? new_socket, client_addr = tcp_server_socket.accept()
# 5驶悟、為這個(gè)客戶端服務(wù)
? ? ? ? gevent.spawn(target=service_client, args=(new_socket,))
"""作用: 創(chuàng)建一個(gè)子進(jìn)程【args里面的是元組, 所以要加一個(gè)逗號(hào)"""
? ? ? ? # new_socket.close()
# 6、關(guān)閉監(jiān)聽(tīng)套接字
? ? tcp_server_socket.close(new_socket)
if __name__ =='__main__':
main()
六贬丛、54_單進(jìn)程單線程非阻塞并發(fā)服務(wù)器
"""單進(jìn)程單線程非阻塞"""
import socket
import time
# 1撩银、創(chuàng)建一個(gè)Tcp服務(wù)端
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_server_socket.bind(("", 7890))
"""綁定端口"""
tcp_server_socket.listen(128)
"""把套接字變?yōu)楸O(jiān)聽(tīng)的; 【listen(x):同時(shí)可以有x個(gè)客戶端連接】"""
tcp_server_socket.setblocking(False)
"""
【.recv():阻塞】
【.setblocking(False):設(shè)置套接字為非阻塞的方式】
"""
client_soket_list =list()
"""設(shè)置一個(gè)客戶端的空列表"""
while True:
time.sleep(1)
try:
# 2、阻塞中等待客戶端連接
? ? ? ? new_socket, new_addr = tcp_server_socket.accept()
except Exception as ret:
print("---沒(méi)有新的客戶端到來(lái)---")
else:
print("---只要沒(méi)有產(chǎn)生異常,就表明來(lái)了一個(gè)新的客戶端---")
new_socket.setblocking(False)
"""設(shè)置套接字為非阻塞的方式"""
? ? ? ? client_soket_list.append(new_socket)
for client_soketin client_soket_list:
try:
recv_data = new_socket.recv(1024).decode("utf-8")
"""【接收】:每次接收x個(gè)字節(jié)"""
? ? ? ? except Exception as ret:
# print(ret)? #方便用于進(jìn)行調(diào)試
? ? ? ? ? ? print("---這個(gè)客戶端沒(méi)有發(fā)送過(guò)來(lái)數(shù)據(jù)---")
else:
print("---沒(méi)有異常---")
print(recv_data)
if recv_data:
# 對(duì)方發(fā)送過(guò)來(lái)數(shù)據(jù)
? ? ? ? ? ? ? ? print("---客戶端發(fā)送過(guò)來(lái)了數(shù)據(jù)---")
else:
# 對(duì)方調(diào)用了close導(dǎo)致recv返回
? ? ? ? ? ? ? ? client_soket_list.remove(client_soket)
client_soket.close()
print("---客戶端已經(jīng)關(guān)閉了---")