%# -*- coding: utf-8-unix -*- \section{TCP通信与Web服务器} \label{sec:c2_s2} \subsection{实验目的} \label{subsec:c2_s2_object} 掌握Python中TCP套接字编程的基础知识,理解HTTP报文格式, 了解开发一个简单Web服务器的流程。 \subsection{实验内容} \label{subsec:c2_s2_content} 使用Python开发一个一次处理一个HTTP请求的Web服务器。 Web服务器接受并解析HTTP请求,从服务器的文件系统中获取请求的文件, 创建一个HTTP响应消息,该消息由前面带有首部行信息的请求文件组成, 然后将响应直接发送给客户端。如果服务器中不存在请求的文件, 则服务器将发送HTTP“404 not Found”的消息给客户端。 \subsection{实验原理、方法和手段} \label{subsec:c2_s2_principle} 基于TCP协议的面向客户/服务器的工作流程是: 在服务器端首先启动服务器调用socket( )创建套接字; 然后调用bind( )指定服务器socket地址(IP地址+端口号); 再调用listen( )让服务器做好侦听准备,并规定好请求队列的长度, 然后服务器进入阻塞状态,等待客户的连接请求; 最后通过accept( )来接收连接请求,并获得客户的socket地址。 在客户端,客户调用socket( )创建套接字,然后调用connect( )和服务器建立连接。 连接建立成功后,客户和服务器之间就可以通过调用read( )和write( )来接收和发送数据。 一旦数据传输结束,服务器和客户通过调用close( )来关闭套接字。具体流程图如下图所示。 \begin{figure}[!htp] \centering \includegraphics[width=6cm]{c2_tcp-flow} \caption{面向连接客户/服务器流程图} \label{fig:c2_udp-flow} \end{figure} \subsection{实验条件} \label{subsec:c2_s2_requirement} \begin{itemize} \item 装有python环境的电脑两台; \item 局域网环境; \item 部分代码(实验步骤中已给出)。 \end{itemize} \subsection{实验步骤} \label{subsec:c2_s2_procedure} 开发一个简单的Web服务器,一次处理一个请求,具体要求如下: \begin{enumerate} \item 当收到请求时创建一个连接套接字; \item 通过这个连接套接字接收HTTP请求; \item 解释HTTP请求以确定所请求的特定文件; \item 从服务器的文件系统获得请求的文件; \item 创建一个由请求的文件组成的HTTP响应报文; \item 通过TCP连接返回响应。 \end{enumerate} 补充完善下面的的服务器代码,完成要求功能。 运行服务器代码,在不同主机上的使用浏览器发送请求测试服务器,分析并记录结果。 \begin{code}[python] #import socket module from socket import * #准备服务器端socket serverSocket = socket(AF_INET, SOCK_STREAM) #按需补充代码 while True: #建立连接 print 'Ready to serve...' connectionSocket, addr = #按需补充 try: message = #按需补充 filename = message.split()[1] f = open(filename[1:]) #通过socket发送HTTP首部行 outputdata = #按需补充 #将请求文件的内容发送到客户端 for i in range(0, len(outputdata)): connectionSocket.send(outputdata[i]) connectionSocket.close() except IOError: #发送未找到文件的响应消息 #按需补充代码 #关闭客户端socket #按需补充代码 serverSocket.close() \end{code} \subsection{思考题} \label{subsec:c2_s2_rethink} 本实验中的Web服务器一次只能处理一个HTTP请求,请自行查阅线程知识, 修改代码,实现一个能够同时处理多个请求的多线程服务器。 \subsection{注意事项及有关说明} \label{subsec:c2_s2_notice} 将HTML文件放在服务器代码同一目录中。运行服务器程序。 确定运行服务器的主机的IP地址(例如,128.238.251.26)。 从另一个主机打开浏览器并提供相应的URL。 例如:\url{http://128.238.251.26:6789/HelloWorld.html}。 “HelloWorld.html”是放置在服务器目录中的文件的名称。 6789为端口号,如果省略则使用默认端口号80。 \subsection{考核方法} \label{subsec:c2_s2_criterion} 同实验\ref{sec:c2_s1}。