一、实验目的
在本课程中,你已经实现了互联网基础设施的重要部分。这个检查点不是关于实现,而是关于测量实际的互联网并报告特定路径的长期统计数据。
二、实验内容
1.收集数据
选择一个远程主机,其往返时间(RTT)从你的虚拟机至少需要100毫秒。一些可能的选项包括:www.cs.ox.ac.uk (英国牛津大学计算机系服务器)
162.105.253.58 (中国北京大学计算机中心)
www.canterbury.ac.nz (新西兰坎特伯雷大学服务器)
41.186.255.86 (卢旺达MTN)
首选:从你的位置选择一个RTT至少为100ms的原始目标
使用mtr或traceroute命令追踪你的虚拟机和这个主机之间的路由。
运行ping至少两小时,以收集这个互联网路径的数据。使用类似ping -D -n -i 0.2 hostname | tee data.txt的命令来保存数据到"data.txt"文件。(-D参数使ping记录每一行的时间戳,-i 0.2使其每0.2秒发送一个“回声请求”ICMP消息。-n参数使其跳过尝试使用DNS反向查找回复IP地址到主机名。)
注意:每0.2秒发送默认大小的ping是可以的,但请不要以比这更快的速度发送流量。
2.分析数据
如果你每秒发送五个ping,持续两小时,你将发送大约36,000个回声请求(= 5 × 3600 × 2),其中我们预期绝大多数在ping输出中收到回复。请使用你选择的编程语言和图形工具,包含:
整个时间间隔的总体传递率是多少?换句话说:收到的回声回复数除以发送的回声请求数是多少?
最长的连续成功ping(连续回复)是多少?
最长的连续丢包(连续未回复)是多少?
“数据包丢失”的事件在时间上是多么独立或相关?换句话说:给定回声请求#N收到回复,回声请求#(N+1)也成功回复的概率是多少?
给定回声请求#N未收到回复,回声请求#(N+1)成功回复的概率是多少?
这些数字(条件传递率)与第一个问题中的总体“无条件”数据包传递率相比如何?丢失是怎样的独立或突发的?
三、实验过程
运行ping -D -n -i 0.2 162.105.253.58 | tee data.txt 这行指令,连接“中国北京大学计算机中心”,收集这个互联网路径的数据
打开桌面上的data.txt文件,查看收集到的数据
安装pip
输入Y以完成安装
用pip安装pandas库,发现报错:error: externally-managed-environment
选择使用pipx解决此问题。输入sudo apt install pipx安装pipx
输入Y确定执行
稍作等待后安装完成
使用pipx ensurepath将其添加到PATH中
现在可以使用 Pipx 而不是 Pip 安装 Python 包。再次尝试安装pandas
编写一个python代码
运行此python程序
运行成功,实验结束。
四、实验体会
1.在实验过程中,我首先选择了远程主机 162.105.253.58,并使用 ping 命令收集数据。按实验要求应至少收集两小时,但本次实验主要目的在于完成这个过程,因此为节省时间,我选择缩短收集时间来完成这个过程。然后,我使用 pandas 库对数据进行处理和分析。最后,我使用python计算了整个时间间隔的总体传递率、最长的连续成功 ping 和连续丢包、数据包丢失的独立性或相关性等指标。这些数据为我们提供了互联网路径的性能和稳定性的详细信息。
2.这次实验遇到的主要问题是运行pip install时,通常会收到一个错误提示:error: externally-managed-environment,即“外部管理环境”错误,但这不是一个 bug。完整错误信息如下:
$ sudo pip3 install please-cli
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try 'pacman -S
python-xyz', where xyz is the package you are trying to
install.
If you wish to install a non-Arch-packaged Python package,
create a virtual environment using 'python -m venv path/to/venv'.
Then use path/to/venv/bin/python and path/to/venv/bin/pip.
If you wish to install a non-Arch packaged Python application,
it may be easiest to use 'pipx install xyz', which will manage a
virtual environment for you. Make sure you have python-pipx
installed via pacman.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
“外部管理环境”错误背后的原因:Manjaro 22、Ubuntu 23.04、Fedora 38 以及其他的最新发行版中,正在使用 Python 包来实现此增强功能。
这个更新是为了避免「操作系统包管理器 (如pacman、yum、apt) 和 pip 等特定于 Python 的包管理工具之间的冲突」。
这些冲突包括 Python 级 API 不兼容和文件所有权冲突。
解决方案主要有三种:
①直接去掉这个提示,使用
sudo mv /usr/lib/python3.x/EXTERNALLY-MANAGED /usr/lib/python3.x/EXTERNALLY-MANAGED.bk
然后运行pip(3) install package_name 命令来安装python模块。
②使用pipx,这也是我在本实验中用来解决的方案。它会自动为您安装的每个应用程序创建一个新的虚拟环境。不仅。它还创建指向它的链接.local/bin。这样,安装该软件包的用户就可以从命令行中的任何位置运行它。
③使用venv
需要先安装venv,然后安装模块,再使用新的虚拟环境执行py文件。此处不再展开。
五、代码附录
xxx.py
import pandas as pd
# 读取数据文件
data = pd.read_csv('./data.txt', names=['Timestamp', 'Received', 'RTT'])
# 将 'Received' 列转换为布尔类型
data['Received'] = data['Received'].astype(bool)
total_pings = len(data)
successful_pings = data['Received'].sum()
delivery_rate = successful_pings / total_pings
print(f"总体传递率: {delivery_rate:.2f}")
total_pings = len(data)
successful_pings = data['Received'].sum()
delivery_rate = successful_pings / total_pings
print(f"总体传递率: {delivery_rate:.2f}")
from itertools import groupby
def longest_streak(series):
return max((sum(1 for _ in group) for key, group in groupby(series) if key), default=0)
longest_success_streak = longest_streak(data['Received'])
longest_failure_streak = longest_streak(~data['Received'])
print(f"最长连续成功ping: {longest_success_streak}")
print(f"最长连续丢包: {longest_failure_streak}")
# 计算连续请求的成功/失败关联
data['Next_Received'] = data['Received'].shift(-1)
correlated_success = data[(data['Received'] == True) & (data['Next_Received'] == True)].shape[0]
correlated_failure = data[(data['Received'] == False) & (data['Next_Received'] == True)].shape[0]
prob_success_following_success = correlated_success / successful_pings if successful_pings else 0
prob_success_following_failure = correlated_failure / (total_pings - successful_pings) if total_pings - successful_pings else 0
print(f"给定回声请求#N收到回复, #N+1 也成功回复的概率: {prob_success_following_success:.2f}")
print(f"给定回声请求#N未收到回复, #N+1 成功回复的概率: {prob_success_following_failure:.2f}")