今天来用Python手动搭建http服务器
预备知识:
HTTP协议
Hypertext Transfer Protocol 超文本传输协议
协议的总用就是来传输超文本HTML(Hyper TextMarkupLanguage)
C/S架构 client-server
B/S架构 browser-server
http服务器的搭建
代码示例:
1 2 3 4 5 6 7 8 9 10 11
| import socket
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_socket.bind(('10.0.42.248',9090)) server_socket.listen(128)
client_socket,client_addr = server_socket.accept()
data = client_socket.recv(1024).decode('utf8') print(data)
|
使用浏览器进行通信访问,发现由于没有设置响应头导致浏览器无法访问:
![This is an test image](/2021/03/14/Python%E6%89%8B%E5%8A%A8%E6%90%AD%E5%BB%BAhttp%E6%9C%8D%E5%8A%A1%E5%99%A8/1.png)
可以正常得到的返回数据是一个请求头:GET / HTTP/1.1
Host: 10.0.42.248:9090
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
浏览器发送请求头服务器发送响应头,因此需要设置响应头:
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import socket
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_socket.bind(('0.0.0.0',9090)) server_socket.listen(128)
client_socket,client_addr = server_socket.accept()
data = client_socket.recv(1024).decode('utf8') print(data)
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('\n'.encode('utf8'))
client_socket.send('hello world'.encode('utf8'))
|
![This is an test image](/2021/03/14/Python%E6%89%8B%E5%8A%A8%E6%90%AD%E5%BB%BAhttp%E6%9C%8D%E5%8A%A1%E5%99%A8/2.png)
HTTP请求
1 2 3 4 5 6 7 8 9
| #请求头 #GET /favicon.ico HTTP/1.1 #GET 请求方式,有GET/POST/PUT/DELETE... /表示请求路径 #Host: 10.0.42.248:9090 #请求的地址 #Connection: keep-alive #User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36 #用户代理就像浏览器一样 #Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8 #Referer: http://10.0.42.248:9090/ #Accept-Encoding: gzip, deflate #Accept-Language: zh-CN,zh;q=0.9
|
根据不同的请求响应不同的内容
![This is an test image](/2021/03/14/Python%E6%89%8B%E5%8A%A8%E6%90%AD%E5%BB%BAhttp%E6%9C%8D%E5%8A%A1%E5%99%A8/3.png)
附上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import socket
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_socket.bind(('0.0.0.0',9090)) server_socket.listen(128) while True: client_socket,client_addr = server_socket.accept() data = client_socket.recv(1024).decode('utf8') print('接收到{}的访问数据:\n'.format(client_addr[0])) response_head = 'HTTP/1.1 200 OK\n' path = '/' response_body = 'Hello World' first_line = (data.splitlines()[0]) path = first_line.split(' ')[1] if path == '/login': response_body = 'You Are In Login Surface' elif path == '/register': response_body = 'You Are In Register Surface' elif path == '/' : response_body = 'Your IP Is \n\n\n' + repr(client_addr[0]) else : response_head = 'HTTP/1.1 404 Not Found\n' response_body = '404 NOT FOUND' response_head += 'content-type:text/html\n' response_head += '\n' client_socket.send(response_head.encode('utf8')) client_socket.send(response_body.encode('utf8'))
|
最后一步,就是面向对象的封装咯~;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import socket class My_server(object): def __init__(self,IP,port): self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.IP = IP self.port = port self.socket.bind((IP,port)) self.socket.listen(128) def run_server(self): while True: client_socket,client_addr = self.socket.accept() data = client_socket.recv(1024).decode('utf8') print('接收到{}的访问数据'.format(client_addr[0])) response_head = 'HTTP/1.1 200 OK\n' path = '/' response_body = 'Hello World' first_line = (data.splitlines()[0]) path = first_line.split(' ')[1] if path == '/login': response_body = 'You Are In Login Surface' elif path == '/register': response_body = 'You Are In Register Surface' elif path == '/' : response_body = 'Your IP Is \n\n\n' + repr(client_addr[0]) else : response_head = 'HTTP/1.1 404 Not Found\n' response_body = '404 NOT FOUND' response_head += 'content-type:text/html\n' response_head += '\n' client_socket.send(response_head.encode('utf8')) client_socket.send(response_body.encode('utf8')) my_server = My_server('10.0.42.248',9090) my_server.run_server()
|