目录
一、向http服务器发送请求
import socket
# 1.创建套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.建立连接
tcp_client_socket.connect(("www.icoderi.com", 80))
# 3.拼接请求协议
# 3.1 请求行
request_line = "GET / HTTP/1.1\r\n"
# 3.2 请求头
request_header = "Host:www.icoderi.com\r\n"
# 3.3 请求空行
request_blank = "\r\n"
# 整体拼接
request_data = request_line + request_header + request_blank
# 4.发送请求协议
tcp_client_socket.send(request_data.encode())
# 5.接收服务器响应
recv_data = tcp_client_socket.recv(4096)
recv_text = recv_data.decode()
# 找到响应数据中的html内容
loc = recv_text.find("<html>")
html_data = recv_text[loc:]
print(html_data)
# 关闭连接
tcp_client_socket.close()
打印结果:
二、制作http服务器
2.1 返回固定字符串内容
import socket
def request_handler(new_client_socket, ip_port):
"""接收信息,并且做出响应"""
# 接收客户端浏览器发送的请求协议
request_data = new_client_socket.recv(1024) # 接收请求报文
# 判断协议是否为空
if not request_data:
print("%s客户端已下线!" % str(ip_port))
new_client_socket.close()
else:
# 响应行
response_line = "HTTP/1.1 200 OK\r\n"
# 响应头
response_header = "Server:Python20WS/2.1\r\n"
# 响应空行
response_blank = "\r\n"
# 响应主体
response_body = "Hello World"
# 拼接响应报文
response_data = response_line + response_header + response_blank + response_body
# 发送响应报文
new_client_socket.send((response_data.encode()))
# 关闭连接
new_client_socket.close()
def main():
"""主函数"""
# 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_server_socket.bind(("", 8080))
# 设置监听,让套接字由主动变为被动接收
tcp_server_socket.listen(128)
# 接收客户端连接 定义函数
new_client_socket, ip_port = tcp_server_socket.accept()
# 接收请求并作出响应
request_handler(new_client_socket, ip_port)
if __name__ == '__main__':
main()
结果:
在浏览器中搜索http://127.0.0.1:8080
但是当前的服务器只能接收一个客户端的一次请求,如果想接收多个客户端的多个请求就需要用到循环和多线程:
import socket
from threading import Thread
def request_handler(new_client_socket, ip_port):
"""接收信息,并且做出响应"""
# 接收客户端浏览器发送的请求协议
request_data = new_client_socket.recv(1024) # 接收请求报文
print(request_data)
# 判断协议是否为空
if not request_data:
print("%s客户端已下线!" % str(ip_port))
new_client_socket.close()
else:
# 响应行
response_line = "HTTP/1.1 200 OK\r\n"
# 响应头
response_header = "Server:Python20WS/2.1\r\n"
# 响应空行
response_blank = "\r\n"
# 响应主体
response_body = "Hello World"
# 拼接响应报文
response_data = response_line + response_header + response_blank + response_body
# 发送响应报文
new_client_socket.send((response_data.encode()))
# 关闭连接
new_client_socket.close()
def main():
"""主函数"""
# 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_server_socket.bind(("", 8080))
# 设置监听,让套接字由主动变为被动接收
tcp_server_socket.listen(128)
while True:
# 接收客户端连接 定义函数
new_client_socket, ip_port = tcp_server_socket.accept()
print("新的客户端%s已连接!" % str(ip_port))
# 接收请求并作出响应
t1 = Thread(target=request_handler, args=(new_client_socket, ip_port))
t1.start()
if __name__ == '__main__':
main()
打印结果:
2.2 返回固定页面
import socket
from threading import Thread
def request_handler(new_client_socket, ip_port):
"""接收信息,并且做出响应"""
# 接收客户端浏览器发送的请求协议
request_data = new_client_socket.recv(1024) # 接收请求报文
print(request_data)
# 判断协议是否为空
if not request_data:
print("%s客户端已下线!" % str(ip_port))
new_client_socket.close()
else:
# 响应行
response_line = "HTTP/1.1 200 OK\r\n"
# 响应头
response_header = "Server:Python20WS/2.1\r\n"
# 响应空行
response_blank = "\r\n"
# 响应主体
# 返回字符串内容
# response_body = "Hello World"
# 返回固定页面
with open("static/index.html","rb") as file:
response_body = file.read()
# 拼接响应报文
response_data = (response_line + response_header + response_blank).encode() + response_body
# 发送响应报文
new_client_socket.send((response_data))
# 关闭连接
new_client_socket.close()
def main():
"""主函数"""
# 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_server_socket.bind(("", 8080))
# 设置监听,让套接字由主动变为被动接收
tcp_server_socket.listen(128)
while True:
# 接收客户端连接 定义函数
new_client_socket, ip_port = tcp_server_socket.accept()
print("新的客户端%s已连接!" % str(ip_port))
# 接收请求并作出响应
t1 = Thread(target=request_handler, args=(new_client_socket, ip_port))
t1.start()
if __name__ == '__main__':
main()
前端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<h1>网页测试</h1>
</body>
</html>
结果:
2.3 返回指定的页面
事先准备好前端模板,python服务端代码与static文件夹在同级目录下
test1.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Test1</h1>
</body>
</html>
test2.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Test2</h1>
</body>
</html>
python服务端:
import socket
from threading import Thread
def request_handler(new_client_socket, ip_port):
"""接收信息,并且做出响应"""
# 接收客户端浏览器发送的请求协议
request_data = new_client_socket.recv(1024) # 接收请求报文
# print(request_data)
# 判断协议是否为空
if not request_data:
print("%s客户端已下线!" % str(ip_port))
new_client_socket.close()
else:
# 根据客户端浏览器请求的资源路径,返回请求资源
# 1.把请求协议解码,得到请求报文的字符串
request_text = request_data.decode()
# 2.得到请求行
# 2.1 查找 第一个\r\n出现的位置
loc = request_text.find("\r\n")
# 2.2 截取字符串,从开头截取到 第一个\r\n出现的位置
request_line = request_text[:loc]
# print(request_line)
# 2.3 把请求行按照空格拆分,得到列表
request_line_list = request_line.split(" ")
# 2.4 得到请求资源路径
file_path = request_line_list[1]
print("%s 正在请求:%s" % (str(ip_port), file_path))
# 响应行
response_line = "HTTP/1.1 200 OK\r\n"
# 响应头
response_header = "Server:Python20WS/2.1\r\n"
# 响应空行
response_blank = "\r\n"
# 响应主体
# 返回字符串内容
# response_body = "Hello World"
# 返回固定页面
try:
with open("static"+file_path,"rb") as file:
response_body = file.read()
except Exception as e:
# 重新修改响应行为 404
response_line = "HTTP/1.1 404 Not Found\r\n"
response_body = "Error! %s " % str(e)
response_body = response_body.encode()
# 拼接响应报文
response_data = (response_line + response_header + response_blank).encode() + response_body
# 发送响应报文
new_client_socket.send((response_data))
# 关闭连接
new_client_socket.close()
def main():
"""主函数"""
# 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_server_socket.bind(("", 8080))
# 设置监听,让套接字由主动变为被动接收
tcp_server_socket.listen(128)
while True:
# 接收客户端连接 定义函数
new_client_socket, ip_port = tcp_server_socket.accept()
print("新的客户端%s已连接!" % str(ip_port))
# 接收请求并作出响应
t1 = Thread(target=request_handler, args=(new_client_socket, ip_port))
t1.start()
if __name__ == '__main__':
main()
结果:
下一篇:
python socket 制作http服务器 (面向对象封装)
本文含有隐藏内容,请 开通VIP 后查看