计算机网络套接字编程作业2-1:Web服务器——选做任务5

任务要求:目前,这个 Web 服务器一次只处理一个 HTTP 请求。请实现一个能同时处理多个 请求的多线程服务器。首先创建一个主线程,在固定端口监听客户端请求。当从客户端 收到 TCP 连接请求时,它将通过另一个端口建立 TCP 连接,并在另外的单独线程中为 客户端请求提供服务。这样在每个请求/响应对的独立线程中将有一个独立的 TCP 连接。

服务器代码实现:

from socket import *
import sys
import threading

def Server(connectionSocket, addr):
    print('Waiting: ', addr)
    try:
        # Receives the request message from the client
        message = connectionSocket.recv(1024).decode()

        # Extract the path of the requested object from the message
        # The path is the second part of HTTP header, identified by [1]
        filename = message.split()[1]

        # Because the extracted path of the HTTP request includes
        # a character '/', we read the path from the second character
        f = open(filename[1:])

        # Store the entire content of the requested file in a temporary buffer
        outputdata = f.read()
        f.close()

        # Send the HTTP response header line to the connection socket
        header = 'HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: text/html\r\nContent-Length: %d\r\n\r\n' % (
            len(outputdata))
        connectionSocket.send(header.encode())

        # Send the content of the requested file to the connection socket
        for i in range(0, len(outputdata)):
            connectionSocket.send(outputdata[i].encode())

        # Close the client connection socket
        connectionSocket.close()

    except IOError:
        # Send HTTP response message for file not found
        outputdata = 'HTTP/1.1 404 Not Found\r\n\r\n'
        print(outputdata)
        connectionSocket.send(outputdata.encode())

        # Close the client connection socket
        connectionSocket.close()


serverSocket = socket(AF_INET, SOCK_STREAM)
serverport = 12000
serverSocket.bind(('', serverport))
serverSocket.listen(5)
print('Please wait for connection')
while True:
    connectionSocket, addr = serverSocket.accept()
    thread = threading.Thread(target=Server, args=(connectionSocket, addr))
    thread.start()
serverSockect.close()

客户端的代码,我愚蠢地列出了五个线程:

from socket import *
import threading

def client_thread(filename='AfterThen.html', i=1):
    clientSocket = socket(AF_INET, SOCK_STREAM)
    servername = '127.0.0.1'
    serverport = 12000
    clientSocket.connect((servername, serverport))
    message = '''GET /%s HTTP/1.1\r\nHost: %s:%d\r\nConnection: close\r\nUser-Agent: Mozilla/5.0\r\n\r\n''' % (
    filename, servername, serverport)
    clientSocket.send(message.encode())
    data = 1
    samplename = 'sample%d.txt' % i
    with open(samplename, 'w') as f:
        while data:
            data = clientSocket.recv(1024)
            f.write(data.decode())
        f.close()
    clientSocket.close()
    print('\r\nClient %d has received the message!\r\n' % i)


thread_client_one = threading.Thread(target=client_thread, args=('AfterThen.html', 1))
thread_client_two = threading.Thread(target=client_thread, args=('AfterThen.html', 2))
thread_client_three = threading.Thread(target=client_thread, args=('nothing.html', 3))
thread_client_four = threading.Thread(target=client_thread, args=('AfterThen.html', 4))
thread_client_five = threading.Thread(target=client_thread, args=('nothing.html', 5))

thread_client_one.start()
thread_client_two.start()
thread_client_three.start()
thread_client_four.start()
thread_client_five.start()

文件的html为AfterThen.html,nothing.html是不存在的。

任务结果记录:

1.python版本:3.9

2.验证多线程正确运行的验证方案

编写客户端代码,其中采用多线程方式。在客户端代码中,我设置了5个线程。每个客户线程client_thread在接收完服务器报文后都将报文写入相应的sample.txt(如编号为1的client_thread,将报文写入sample1.txt。其中编号不是线程名字,是我按照程序书写顺序给予线程的编号。),并在客户端运行窗口上打印出“Client相应编号has received the message!”

如果多线程服务器正确运行,服务器运行窗口会打印出不同客户线程与服务器建立连接的IP地址及端口号。客户端运行窗口会打印出5条消息,同时在文件夹中会生成5个sample相应编号.txt文件,打开文件,报文内容与任务4的客户端截图类似,如图1与图2。

图 1 任务4的客户端截图-文件存在

图 2 任务4的客户端截图-文件不存在

3.结果截图

(1)服务器运行窗口截图

(2)客户端运行窗口截图

(3)5个sample相应编号.txt文件截图

(4)sample1.txt截图

(5)sample2.txt截图

(6)sample3.txt截图

(7)sample4.txt截图

(8)sample5.txt截图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值