计算机网络——自顶向下方法(第七版)Socket Programming Assignment 1:WebServer
这部分回顾Socket Programming Assignment 1: WebServer。
参考资料:
- https://github.com/jzplp/Computer-Network-A-Top-Down-Approach-Answer/blob/master/Chapter-2
- https://github.com/moranzcw/Computer-Networking-A-Top-Down-Approach-NOTES
简介
此次作业的目的是是熟悉TCP套接字编程,主要任务如下:
- 实现基本的服务器
- 实现多线程服务器
- 实现客户端
文件路径结构如下:
Socket1_WebServer/
|-- HelloWorld.html
|-- client.py
|-- web_server.py
`-- web_server_multi.py
文件解释如下:
- HelloWorld.html:服务器中文件;
- web_server.py:基本服务器;
- web_server_multi.py:多线程服务器;
- client.py:客户端
网页内容
HelloWorld.html:
<!DOCTYPE html>
<html>
<head>
<title>Test web server</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
基本服务器
代码比较简单,注意点有如下:
- header中每个部分需要后跟\r\n表示结束,整个header部分需要后跟\r\n表示header结束;
- serverName为表示ip地址为localhost
web_server.py代码如下:
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
#Fill in start
serverPort = 12000
serverSocket.bind(("", serverPort))
serverSocket.listen(1)
#Fill in end
while True:
#Establish the connection
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept() #Fill in start #Fill in end
try:
message = connectionSocket.recv(1024).decode()#Fill in start #Fill in end
print(message)
filename = message.split()[1]
print(filename)
f = open(filename[1:])
outputdata = f.readlines()#Fill in start #Fill in end
print(outputdata)
#Send one HTTP header line into socket
#Fill in start
# 每个header需要后跟\r\n表示结束, header部分需要后跟\r\n表示header结束
connectionSocket.send('HTTP/1.1 200 OK\r\n\r\n'.encode())
#Fill in end
#Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i].encode())
f.close()
connectionSocket.close()
except IOError:
#Send response message for file not found
#Fill in start
connectionSocket.send('HTTP/1.1 404 Not Found\r\n\r\n'.encode())
#Fill in end
#Close client socket
#Fill in start
connectionSocket.close()
#Fill in end
serverSocket.close()
启动服务器:
python web_server.py
测试:
多线程服务器
每次碰到一个请求,多开一个进程即可,web_server_multi.py代码如下:
#import socket module
from socket import *
import threading
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
#Fill in start
serverPort = 12000
serverSocket.bind(('', serverPort))
serverSocket.listen(1)
def response(connectionSocket):
try:
message = connectionSocket.recv(1024).decode()#Fill in start #Fill in end
print(message)
filename = message.split()[1]
print(filename)
f = open(filename[1:])
outputdata = f.readlines()#Fill in start #Fill in end
print(outputdata)
#Send one HTTP header line into socket
#Fill in start
connectionSocket.send('HTTP/1.1 200 OK\r\n\r\n'.encode())
#Fill in end
#Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i].encode())
f.close()
connectionSocket.close()
except IOError:
#Send response message for file not found
#Fill in start
connectionSocket.send('HTTP/1.1 404 Not Found\r\n\r\n'.encode())
#Fill in end
#Close client socket
#Fill in start
connectionSocket.close()
#Fill in end
#Fill in end
while True:
#Establish the connection
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept() #Fill in start #Fill in end
thread = threading.Thread(target=response, args=(connectionSocket,))
thread.start()
serverSocket.close()
启动服务器:
python web_server_multi.py
测试:
客户端
参考课本2.7.2的客户端编写即可,这里输入有三个参数,分别是server_host,server_port,filename,client.py代码如下:
import sys
from socket import *
def main():
server_host = sys.argv[1]
server_port = sys.argv[2]
filename = sys.argv[3]
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((server_host, int(server_port)))
clientSocket.send(f"GET /{filename} HTTP/1.1\r\n\r\n".encode())
while True:
rawdata = clientSocket.recv(1024)
data = rawdata.decode()
if len(data) == 0:
break
print(data)
clientSocket.close()
if __name__ == '__main__':
main()
启动服务器以及客户端:
python web_server.py
python client.py localhost 12000 HelloWorld.html
实验结果:
HTTP/1.1 200 OK
<!DOCTYPE html>
<html>
<head>
<title>Test web server</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere