题目要求
You will develop a web server that handles one HTTP request at a time. Your web server should accept and parse the HTTP request, get the requested file from the server’s file system, create an HTTP response message consisting of the requested file preceded by header lines, and then send the response directly to the client. If the requested file is not present in the server, the server should send an HTTP “404 Not Found” message back to the client.
- 从浏览器请求文件,若存在则请求成功,显示文件。若失败则返回404.
服务器代码
from socket import *
HOST = ''
PORT = 6789
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(1)
while True:
print('waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept()
try:
data = tcpCliSock.recv(BUFSIZE)
#print(data) #data是一个get的http请求报文
filename = data.split()[1] #filename = /HelloWorld.html
#print(filename[1:])
f = open(filename[1:]) #f = HelloWorld.html
outputdata = f.read()
header = 'HTTP/1.1 200 OK\r\n\r\n' #回复报文
tcpCliSock.send(header.encode())
for i in range(0, len(outputdata)):
tcpCliSock.send(outputdata[i].encode())
tcpCliSock.close()
except IOError:
header = 'HTTP/1.1 404 NOT FOUND\r\n\r\n'
tcpCliSock.send(header.encode())
tcpCliSock.close()
tcpSerSock.close()
代码注意点
- 写
header
时注意格式,比如如果还有content type
这种字段的话,每个字段之间相隔\r\n
,然后报文结束以\r\n\r\n
结束,否则后面请求文件内容会显示在回复报文中。 - 看socket文档时
send(bytes())
这个函数里面的是bytes,所以不能直接发送str
,要做一个str
和bytes
之间的转换。
运行过程
- 运行该webserber.py 代码
- 准备HelloWorld.html,内容为
<head>Hello World!</head>
。在浏览器输入ip:6789:HelloWord.html
,会显示文档内容。
- 如果输入不存在的文档,比如
ip:6789:Hello.html
,会显示HTTP ERROR 404
,(这里我一一直以为反应在报文里,其实不是,而是反应在页面上,当代码把404改成403就会显示HTTP ERROR 403
)
参考:myk的GitHub