固定页面
import socket
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 端口复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定地址
tcp_server_socket.bind(("",8080)) # 我们的客户端是浏览器,所以不用写了,在本地写服务器,所以ip地址就可以默认本机地址
# 设置监听
tcp_server_socket.listen(128)
while True:
# 接受链接请求
client_socket, addr = tcp_server_socket.accept()
# 接受数据
recv_data = client_socket.recv(1024)
if len(recv_data) == 0:
print("客户端关闭了!!!")
break
print(recv_data.decode())
# 打开资源文件
f = open("D:/rfpython/资源文件/0001.jpg", "rb")
# 存放了图片资源
file_data = f.read()
f.close()
# 响应行
responce_line = "HTTP/1.1 200 OK\r\n"
# 响应头
responce_head = "server:py1.0\r\n"
# 响应体
responce_body = file_data
# 响应数据
responce_data = (responce_line + responce_head + "\r\n").encode() +responce_body
# 发送数据
client_socket.send(responce_data)
client_socket.close()浏览器输入127.0.0.1:8080出现图片
指定页面
import socket
tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 端口复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定地址
tcp_server_socket.bind(("",8080)) # 我们的客户端是浏览器,所以不用写了,在本地写服务器,所以ip地址就可以默认本机地址
# 设置监听
tcp_server_socket.listen(128)
while True:
# 接受链接请求
client_socket, addr = tcp_server_socket.accept()
# 接受数据
recv_data = client_socket.recv(1024)
if len(recv_data) == 0:
print("客户端关闭了!!!")
break
# 解码
recv_data = recv_data.decode()
print(recv_data)
# 对请求报文进行切割
path_list = recv_data.split(" ")
print("列表!", path_list)
# 请求资源路径 /index.html /index2.html
request_path = path_list[1]
# 打开资源文件
f = open("D:/rfpython/资源文件" + request_path, "rb")
# 存放了图片资源
file_data = f.read()
f.close()
# 响应行
responce_line = "HTTP/1.1 200 OK\r\n"
# 响应头
responce_head = "server:py1.0\r\n"
# 响应体
responce_body = file_data
# 响应数据
responce_data = (responce_line + responce_head + "\r\n").encode() +responce_body
# 发送数据
client_socket.send(responce_data)
client_socket.close()浏览器输入127.0.0.1:8080/0002.jpg
可以看到我们把请求报文切割成列表,列表的第二个元素就是我们需要的地址
浏览器输入127.0.0.1:8080/0003.jpg
同理
这就是根据指定的网址打开页面
异常捕获
# 异常捕获(防止出现异常的时候 服务器直接崩溃)
try:
# 打开资源文件
f = open("D:/rfpython/资源文件" + request_path, "rb")
# 存放了图片资源
file_data = f.read()
f.close()
except Exception as e:
# 浏览器访问的网址里的资源不存在的情况下
# 证明文件不存在
print("异常信息:", e)
# 访问不成功的情况下的响应报文
responce_line = "HTTP/1.1 404 NOT FOUND\r\n"
responce_head = "sever:py1.0\r\n"
responce_body = "sorry, not found"
# 把没有找到相应文件的信息发给浏览器
responce_data = responce_line + responce_head + "\r\n"+ responce_body
client_socket.send(responce_data.encode())
client_socket.close()
else:在浏览器中输入一个不存在的文件127.0.0.1:8080/xxx.html
多任务
import multiprocessing
# 创建多进程
sub_process = multiprocessing.Process(target=handler_client_request,args=(client_socket,))
sub_process.start()可以看到我们能同时多个浏览器访问
动态绑定端口
import socket
import multiprocessing
# 系统模块
import sys
# argv 是我们在终端命令中的(python3 9-sys.py 9090) 一个列表,列表中存放的是9-sys.py 9090
# argv[1]:9090 ==> 字符串类型
class WebServer:
# 初始化方法
def __init__(self, port=8080):
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用
self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定地址
self.tcp_server_socket.bind(("", int(port))) # 在ubuntu写服务器
# 设置监听
self.tcp_server_socket.listen(128)
@staticmethod
def handler_client_request(client_socket):
"""和浏览器进行数据交换的函数"""
# 接受数据
recv_data = client_socket.recv(1024)
if len(recv_data) == 0:
print("客户端关闭了!!!")
return
# 解码
recv_data = recv_data.decode()
print(recv_data)
# 对请求报文进行切割
path_list = recv_data.split(" ")
print("列表!", path_list)
# 请求资源路径 /index.html /index2.html
request_path = path_list[1]
# 异常捕获(防止出现异常的时候 服务器直接崩溃)
try:
# 打开资源文件
if request_path == '/':
# 打开资源文件
f = open("/home/yrf/Pictures/0001.jpg", "rb") # 不指定的时候默认的界面
# 存放了图片资源
file_data = f.read()
f.close()
else:
f = open("/home/yrf/Pictures" + request_path, "rb")
# 存放了图片资源
file_data = f.read()
f.close()
except Exception as e:
# 浏览器访问的网址里的资源不存在的情况下
# 证明文件不存在
print("异常信息:", e)
# 访问不成功的情况下的响应报文
responce_line = "HTTP/1.1 404 NOT FOUND\r\n"
responce_head = "sever:py1.0\r\n"
responce_body = "sorry, not found"
# 把没有找到相应文件的信息发给浏览器
responce_data = responce_line + responce_head + "\r\n" + responce_body
client_socket.send(responce_data.encode())
client_socket.close()
else:
# 浏览器访问的网址里的资源存在的情况下
# 响应行
responce_line = "HTTP/1.1 200 OK\r\n"
# 响应头
responce_head = "server:py1.0\r\n"
# 响应体
responce_body = file_data
# 响应数据
responce_data = (responce_line + responce_head + "\r\n").encode() + responce_body
# 发送数据
client_socket.send(responce_data)
client_socket.close()
def start(self):
"""控制整个服务器流程的函数
tcp_server_socket:用来接收链接的socket
client_socket:用来处理和浏览器之间的数据交流的socket
"""
while True:
# 接受链接请求
client_socket, addr = self.tcp_server_socket.accept()
# 创建多进程
sub_process = multiprocessing.Process(target=self.handler_client_request,args=(client_socket,))
sub_process.start()
# 调用处理浏览器请求的函数
self.handler_client_request(client_socket)
if __name__ == '__main__':
# 获取动态端口
port = sys.argv[1]
web_server = WebServer(int(port))
web_server.start()效果
