马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
开发步调:
①编写一个TCP服务端步调
②获取欣赏器发送的HTTP哀求报文数据
③读取固定页面数据,把页面数据组装成HTTP相应报文数据发送给欣赏器。
④HTTP相应报文数据发送完成以后,关闭服务于客户端的套接字。
返回固定页面的静态Web服务器开发
1、编写index.html文件
这里先写好一个index.html文件,内容:- <h1>Hello, World!</h1>
- <p>这是一个简单的静态Web服务器</p>
复制代码 2、web服务器开发代码
- import socket
- if __name__ == '__main__':
- # 1.创建套接字
- tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET:IPv4, SOCK_STREAM:TCP协议
- # 2.绑定端口
- tcp_server_socket.bind(('127.0.0.1', 8080)) # 绑定端口
- tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 设置套接字选项,允许地址重用(端口复用)
- # 3.监听
- tcp_server_socket.listen(128) # 监听
- # 4.等待客户端连接
- while True:
- new_socket, client_addr = tcp_server_socket.accept() # 等待客户端连接
- print(f"客户端连接成功: {client_addr}")
- # 5.接收客户端发送的HTTP请求报文数据
- content = new_socket.recv(1024).decode('utf-8') # 接收客户端发送的HTTP请求报文数据
- print(f"HTTP请求报文数据: {content}")
- # 到这里就可以在浏览器访问,这里就能接收到请求报文数据了
- # 6.返回数据给浏览器,这里的数据是index.html文件中的内容
- with open('index.html', 'rb') as file: # 注意:⭐⭐这里是用rb读取,都进来就是二进制流⭐⭐
- file_data = file.read()
- # 7.组装HTTP响应报文数据:⭐⭐响应行、响应头、空行、响应体⭐⭐
- response_line = "HTTP/1.1 200 OK\r\n" # 注意:⭐⭐响应行后面要有\r\n用来换行⭐⭐
- response_header = "Server: CZC/1.1\r\nContent-Type: text/html;charset=utf-8\r\n" # 告诉浏览器返回的数据类型是html,编码是utf-8
- # ⭐⭐组装HTTP响应报文数据,需要以字节流形式发送⭐⭐
- response_data = (response_line + response_header + "\r\n").encode('utf-8') + response_body # 如果前面是r模式读取,这里就需要用encode('utf-8')转换为字节流
- # 8.发送HTTP响应报文数据
- new_socket.send(response_data) # 发送HTTP响应报文数据
- # 9.关闭服务于客户端的套接字
- new_socket.close() # 关闭服务于客户端的套接字
复制代码 留意:
- 这里返回的页面数据是index.html文件中的内容,如果想要返回其他页面数据,只须要修改index.html文件中的内容即可。
- HTTP报文中的相应行、相应头、空行、相应体,须要以字节省情势发送。
- 读取index.html文件中的内容,须要使用rb模式读取,由于文件中的内容是二进制流。如果使用r模式读取,须要使用encode(‘utf-8’)转换为字节省。
- HTTP报文的换行是\r\n,而不是\n。
返回指定页面的静态Web服务器开发
为了打开指定页面,这里先多创建几个html文件,好比:index.html、login.html、register.html、404.html、500.html
根本Web服务器:
- 编写一个TCP服务端步调(七步走)
- 获取欣赏器发送的HTTP哀求报文数据
- 读取固定页面数据,把页面数据组装成HTTP相应报文数据发送给欣赏器。
- HTTP相应报文数据发送完成以后,关闭服务于客户端的套接字。
返回指定页面:
- 获取用户哀求资源路径
- 根据哀求资源路径,读取指定文件的数据
- 组装指定文件数据的相应报文,发送给欣赏器
用户指定页面是写在HTTP哀求报文中的哀求行中的资源路径,好比:GET /login.html HTTP/1.1- import socket
- if __name__ == '__main__':
- # 1.创建套接字
- tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET:IPv4, SOCK_STREAM:TCP协议
- # 2.绑定端口
- tcp_server_socket.bind(('127.0.0.1', 8080)) # 绑定端口
- tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 设置套接字选项,允许地址重用(端口复用)
- # 3.监听
- tcp_server_socket.listen(128) # 监听
- # 4.等待客户端连接
- while True:
- new_socket, client_addr = tcp_server_socket.accept() # 等待客户端连接
- # 5.接收客户端发送的HTTP请求报文数据
- client_request_data = new_socket.recv(4096)
- # 注意:新版浏览器都由自动刷新功能(每隔一段时间不操作,浏览器会自动刷新),所以这里需要判断浏览器是否发送了请求报文数据
- if client_request_data:
- # 如果浏览器发送过来了数据,则需要获取浏览器请求的资源路径
- client_request_data = client_request_data.decode('utf-8') # 把字节流转换为字符串
- # 获取用户请求资源路径
- request_line = client_request_data.split('\r\n')[0] # 获取请求行
- request_line_list = request_line.split(' ') # 把请求行按空格分割成列表
- request_path = request_line_list[1] # 获取请求资源路径
- print(f"请求资源路径: {request_path}")
- if request_path == '/': # ⭐如果用户没有指定访问哪个页面,则默认访问首页
- request_path = '/index.html'
-
- # 根据请求资源路径,读取指定文件的数据
- try:
- with open('.' + request_path, 'rb') as file:
- file_data = file.read()
- except Exception as e:
- # 如果用户请求的资源路径不存在,则返回404页面
- with open('404.html', 'rb') as file: # 读取404页面
- file_data = file.read()
- # 6.组装指定文件数据的响应报文,发送给浏览器
- response_line = "HTTP/1.1 200 OK\r\n" # 注意:⭐⭐响应行后面要有\r\n用来换行⭐⭐
- response_header = "Server: CZC/1.1\r\nContent-Type: text/html;charset=utf-8\r\n" # 告诉浏览器返回的数据类型是html,编码是utf-8
- response_data = (response_line + response_header + "\r\n").encode('utf-8') + file_data # 如果前面是r模式读取,这里就需要用encode('utf-8')转换为字节流
- new_socket.send(response_data) # 发送HTTP响应报文数据
- # 7.关闭服务于客户端的套接字
- new_socket.close()
复制代码 留意:
- 网页标签的的小图标:favicon.ico
- 当用户没有指定访问哪个页面,会报错,
- 以是要加容错,默认访问首页
- 对于不存在的页面,返回自己写的404页面
- 如果返回的是图片,肯定不能加utf-8编码,否则会乱码,由于图片是二进制流,不须要编码
|