%# -*- coding: utf-8-unix -*- \section{套接字基础与UDP通信} \label{sec:c2_s1} \subsection{实验目的} \label{subsec:c2_s1_object} 熟悉Python中UDP套接字编程的基础知识,掌握使用UDP套接字发送和接收数据包, 以及设置正确的套接字超时, 了解Ping应用程序及其在计算数据包丢失率等统计数据方面的有用性。 \subsection{实验内容} \label{subsec:c2_s1_content} 标准的ping使用ICMP,该实验创建一个简单的, 非标准的基于UDP的ping程序。用Python编写一个客户ping程序。 该客户将发送一个简单的ping报文,接收一个从服务器往返的对应pong报文, 并确定从该客户发送ping报文到接收pong报文为止的时延(往返时延RTT)。 要求你的ping程序经UDP向目标服务器发送10个ping报文。 对于每个报文,当对应的pong报文返回时,客户端要确认和打印RTT; 要求考虑分组丢失情况,客户端最多等待1秒,超过该时长则打印丢失报文。 \subsection{实验原理、方法和手段} \label{subsec:c2_s1_principle} UDP提供了无连接通信,且不对传送数据包进行可靠性保证, 适合于一次传输少量数据,UDP传输的可靠性由应用层负责。 常用的UDP端口号有:53(DNS)、69(TFTP)、161(SNMP), 使用UDP协议包括:TFTP、SNMP、NFS、DNS、BOOTP。 UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。 但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高, 适合对可靠性要求不高的应用程序, 或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。 基于UDP协议的无连接客户/服务器的工作流程是: 在服务器端首先启动服务器通过调用socket( )创建套接字, 然后调用bind( )指定服务器socket地址,最后服务器调用recvfrom( )等待接收数据。 在客户端,客户调用socket( )创建套接字,然后调用sendto( )向服务器发送数据。 服务器接收到客户发来数据后,调用sendto( )向客户发送应答数据, 客户调用recvfrom接收服务器发来的应答数据。 一旦数据传输结束,服务器和客户通过调用close( )来关闭套接字。 具体流程如图\ref{fig:c2_udp-flow}所示。 \begin{figure}[!htp] \centering \includegraphics[width=8cm]{c2_udp-flow} \caption{无连接客户/服务器流程图} \label{fig:c2_udp-flow} \end{figure} \subsection{实验条件} \label{subsec:c2_s1_requirement} \begin{itemize} \item 装有python环境的电脑两台; \item 局域网环境; \item 服务器程序(实验步骤中已给出)。 \end{itemize} \subsection{实验步骤} \label{subsec:c2_s1_procedure} 下面的服务器代码中30\%的客户端数据包被模拟为丢失。 请参考该代码,按照实验任务完成ping客户端代码。 注意在运行客户端程序前,需要先运行服务器端代码。 使用客服端ping程序经UDP向目标服务器发送10个ping报文。要求: \begin{enumerate} \item 使用UDP发送ping消息(注意:因为UDP是无连接协议,不需要建立连接。); \item 如果服务器在1秒内响应,则打印该响应消息; 计算并打印每个数据包的往返时间RTT(以秒为单位); \item 否则,打印“请求超时”。 \end{enumerate} 在开发过程中,可以将客户端程序和服务器程序放在同一台电脑上进行测试。 在完成代码调试后,可以尝试将客户端和服务器代码运行在不同网络环境, 记录并分析结果。下面是UDP服务器示例代码: \begin{code}[python] from socket import * # 创建一个UDP套接字(SOCK_DGRAM) serverSocket = socket(AF_INET, SOCK_DGRAM) serverSocket.bind(('', 12000)) while True: rand = random.randint(0, 10) message, address = serverSocket.recvfrom(1024) message = message.upper() # 模拟40%的数据包丢失。 if rand < 4: Continue serverSocket.sendto(message, address) \end{code} \subsection{思考题} \label{subsec:c2_s1_rethink} 尝试修改代码计算所有ping结束时报告最小、最大、平均rtt和计算丢包率(百分比) 以符合标准ping程序的工作方式。 \subsection{考核方法} \label{subsec:c2_s1_criterion} 本次实验需提交一份实验报告和代码文件。报告内容应当包括以下三个部分: \begin{itemize} \item 代码的说明; \item 不同环境下代码运行的结果; \item 对结果的分析和总结体会。 \end{itemize} 本实验评分标准: \begin{enumerate} \item 规定时间内完成实验报告20分; \item 代码正确运行,20分(不能正常运行0分); \item 实验报告格式整洁,20分; \item 实验报告中详细记录了实验过程,在实验中所遇到的问题以及解决方法,20分; \item 实验报告中仔细分析了实验结果,并能提出自己的改进措施,20分。 \end{enumerate}