You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
p2l5wexnu/data/ch_socket/sec_web.tex

152 lines
6.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

%# -*- coding: utf-8-unix -*-
\section{TCP通信与Web服务器}
\label{sec:c:socket:s:web}
\subsection{实验目的}
\label{subsec:c:socket:s:web_object}
熟悉基于Python进行TCP套接字编程的基础知识理解HTTP报文格式
能基于Python编写一个可以一次响应一个HTTP请求
并返回静态文件的简单Web服务器。
\subsection{实验内容}
\label{subsec:c:socket:s:web_content}
利用Python开发一个可以一次处理一个HTTP请求的Web服务器
该服务器可以接受并解析HTTP请求
然后从服务器的文件系统中读取被HTTP请求的文件
并根据该文件是否存在而向客户端发送正确的响应消息,
\subsection{实验原理、方法和手段}
\label{subsec:c:socket:s:web_principle}
基于TCP的面向客户端/服务器在Python实现中的的工作流程是
\begin{enumerate}
\item 首先在服务器端通过调用\texttt{socket()}创建套接字来启动一个服务器;
\item 服务器调用\texttt{bind()}绑定指定服务器的套接字地址IP地址+端口号);
\item 服务器调用\texttt{listen()}做好侦听准备,同时规定好请求队列的长度;
\item 服务器进入阻塞状态,等待客户的连接请求;
\item 服务器通过\texttt{accept()}来接收连接请求并获得客户的socket地址。
\item 在客户端通过调用\texttt{socket()}创建套接字;
\item 客户端调用\texttt{connect()}和服务器建立连接。
\item 连接建立成功后,客户端和服务器之间通过调用\texttt{read()}
\texttt{write()}来接收和发送数据。
\item 数据传输结束后,服务器和客户各自通过调用\texttt{close()}关闭套接字。
\end{enumerate}
注意在不同的计算机语言实现中,上述调用的名字和具体工作流程可能略有不同。
基于Python的TCP客户端/服务器具体工作流程如图\ref{fig:c:socket_tcp-flow}所示。
\begin{figure}[!ht]
\centering
\includegraphics[width=6cm]{tcp-flow}
\caption{面向连接客户/服务器流程图}
\label{fig:c:socket_tcp-flow}
\end{figure}
\subsection{实验条件}
\label{subsec:c:socket:s:web_requirement}
\begin{itemize}
\item 装有python环境的电脑两台
\item 局域网环境;
\item 部分代码(\nameref{subsec:c:socket:s:web_additional}中已给出);
\item Python语言参考手册 -- TCP部分\footnote{可以参考Python3官方手册的
\href{https://docs.python.org/zh-cn/3/library/socket.html}
{套接字}部分,也可以查询其他相关手册}
\item HTTP协议参考手册\footnote{可以参考Mozilla提供的
\href{https://developer.mozilla.org/zh-CN/docs/Web/HTTP/OverView}
{HTTP概述}或者HTTP 1.1版的\href{https://tools.ietf.org/html/rfc2616}{RFC文档}
也可以查询其他相关手册}
\end{itemize}
\subsection{实验步骤}
\label{subsec:c:socket:s:web_procedure}
本实验\nameref{subsec:c:socket:s:web_additional}一节中展示了一份不完整的Web服务器框架代码
学生需要逐步填充代码中不完善的部分并完成一个具有以下功能的简单Web服务器
\begin{enumerate}
\item 服务器收到请求时能创建一个TCP套接字
\item 可以通过这个TCP套接字接收HTTP请求
\item 解析HTTP请求并在操作系统中确定客户端所请求的特定文件
\item 从服务器的文件系统读取客户端请求的文件;
\item 当被请求文件存在时创建一个由被请求的文件组成的“请求成功”HTTP响应报文
\item 当被请求文件不存在时创建“请求目标不存在”HTTP响应报文
\item 通过TCP连接将响应报文发回客户端
\end{enumerate}
在开发过程中,可以使用浏览器访问运行在同一台电脑上的服务器程序进行测试。
在完成代码调试后,可以尝试在不同主机上的使用浏览器发送请求测试服务器,分析并记录结果。
\subsection{进阶任务}
\label{subsec:c:socket:s:web_rethink}
本实验中的Web服务器一次只能处理一个HTTP请求请自行查阅线程知识
修改代码,实现一个能够同时处理多个请求的多线程服务器。
\subsection{注意事项及有关说明}
\label{subsec:c:socket:s:web_notice}
客户端发来的HTTP请求中URL都是相对根“/”的相对路径,
因此需要将服务器文件系统中的某个地址映射为这个“根”。
为了简化工作,建议将服务器程序存放的路径作为这个根,
这样运行服务器程序时,程序会自动从当前运行的路径开始查询文件。
例如:
假设将“HelloWorld.html”这个html文件放置在服务器程序文件存放目录中
服务器运行主机的IP地址为“\texttt{123.234.12.34}”,
6789为服务器监听的端口号。
则从URL\url{http://123.234.12.34:6789/HelloWorld.html}
出发可以获取到“HelloWorld.html”这个文件。
\subsection{考核方法}
\label{subsec:c:socket:s:web_criterion}
本实验需提交一份实验报告和编写的代码文件。报告内容应当包括以下三个部分:
\begin{itemize}
\item 代码的说明;
\item 不同环境下代码运行的结果;
\item 对结果的分析和总结体会。
\end{itemize}
本实验评分标准:
\begin{enumerate}
\item 规定时间内完成实验报告20分
\item 代码正确运行20分不能正常运行0分
\item 实验报告格式整洁20分
\item 实验报告中详细记录了实验过程在实验中所遇到的问题以及解决方法20分
\item 实验报告中仔细分析了实验结果并能提出自己的改进措施20分。
\end{enumerate}
\subsection{附件}
\label{subsec:c:socket:s:web_additional}
基于Python的Web服务器框架程序
\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}