创建基于 UDP 的 Ping 程序

任务描述

本关任务:创建一个非标准的基于 UDP 的ping程序,需要输出数据包的源主机 IP 地址以及往返时延(RTT)。

相关知识

为了完成本关任务,你需要回顾第一个关卡的具体内容,包括:

  1. 创建socket对象;
  2. 发送 UDP 数据;
  3. 接收 UDP 数据;
  4. 设置超时

如果已经忘记了相关的内容,请返回第一关进行复习。

除此之外,你还需要掌握:

  1. Ping 的基本工作原理
  2. 计算往返时延 RTT
Ping 的基本工作原理
  • PING (Packet Internet Groper):因特网包探索器,用于测试网络连接量的程序。在现代操作系统中标准ping程序是一个网络诊断工具,客户端发送一个ping报文,接受一个从服务器返回的pong报文,标准的ping使用互联网控制报文协议( ICMP )。

  • 在本关卡中,您将创建一个非标准的基于 UDP 的ping程序。您的ping程序经 UDP 向目标服务器发送10ping报文,对于每个报文,当对应的pong报文返回时,你的客户要确定和打印 RTT。因为 UDP 是一个不可靠协议,由客户发送的分组可能会丢失。为此,客户不能无限期地等待对ping报文的回答。客户等待服务器回答的时间至多为1秒,如果没有收到回答,客户假定该分组丢失并相应地打印一条反馈信息。

计算往返时延 RTT
  • RTT (Round-Trip Time):往返时延。在计算机网络中它是一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延:

     
      
    1. RTT = 收到数据的时间 - 发送数据的时间
  • 往返延时由三个部分决定:即链路的传播时间、末端系统的处理时间以及路由器的缓存中的排队和处理时间。其中,前面两个部分的值作为一个TCP连接相对固定,路由器中缓存的排队和处理时间会随着整个网络拥塞程度的变化而变化。所以 RTT 的变化在一定程度上反映了网络拥塞程度的变化。

  • 本实验,你需要确定从客户端发送ping报文到接收到pong报文为止的时延。

  • 我们需要使用python中的time模块,该模块中的time()函数可以提供当前时间的时间戳:

     
      
    1. time.time() #表示当前时间的时间戳
编程要求

本实训使用python3进行编程,客户端将采用 UDP 方式连接服务器。你需要建立一个 UDP 套接字,并指定目的IP地址和端口,随之使用一个循环来发送数据包,共循环10次,你需要在右侧编辑器补充代码,完成客户器的功能,具体如下:

  1. 由于评测系统的服务器端文件和客户端文件位于同一台主机,我们可以使用localhost表示服务器端地址。

  2. 端口号为56789

  3. 设置超时时长为1秒。

  4. 客户端发送的内容为Ping x timex表示第几次发送。(你不需要将发送内容输出)

  5. 接收的内容为Receive x: Reply from y RTT = z,你需要将其输出,其中x表示收到第几次的报文,y是服务器的 IP 地址,该地址不包括端口号,z是往返时延 RTT,单位为s,并且保留小数点后两位有效数字,输出时需要加上单位,具体参考预期输出。

  6. 发生丢包时要有反馈信息,并且需要输出,内容为Sequence x: Request timed outx表示第几个数据包报发生丢失,具体参考预期输出。

测试说明

平台会对你编写的代码进行测试:

预期输出: Receive 1: Reply from 127.0.0.1 RTT = 0.80s Receive 2: Reply from 127.0.0.1 RTT = 0.50s Receive 3: Reply from 127.0.0.1 RTT = 0.80s Receive 4: Reply from 127.0.0.1 RTT = 0.50s Sequence 5: Request timed out Receive 6: Reply from 127.0.0.1 RTT = 0.20s Receive 7: Reply from 127.0.0.1 RTT = 0.50s Receive 8: Reply from 127.0.0.1 RTT = 0.80s Receive 9: Reply from 127.0.0.1 RTT = 0.80s Receive 10: Reply from 127.0.0.1 RTT = 0.50s


开始你的任务吧,祝你成功!

from socket import *
import time

#********* Begin *********#
# 指定服务器地址和端口
addressPort = ("localhost", 56789)
#********* End *********#

#********* Begin *********#
# 创建UDP套接字
s = socket(AF_INET, SOCK_DGRAM)
#********* End *********#

#********* Begin *********#
# 设置套接字超时值1秒
s.settimeout(1)
#********* End *********#

i = 1
while i <= 10:
    sendTime = time.time() # 记录发送ping报文的当前时间戳
    try:
        # ********* Begin *********#
        # 生成数据报,编码为bytes,并发送给服务器
        data = bytes("Ping " + str(i) + " time", encoding='utf-8')
        s.sendto(data, addressPort)
        # ********* End *********#

        # ********* Begin *********#
        # 从服务器接收信息,同时也能得到来自服务器的地址,需要输出该地址,(不要输出端口号!)
        # 并且需要计算和输出RTT,具体见编程要求

        data, server_address = s.recvfrom(1024)
        end_time = time.time()  # 记录接收时间
        rtt = round(end_time - sendTime, 2)  # 计算往返时延
        print('Receive %d: Reply from %s RTT = %.2fs' % (i, server_address[0], rtt))

        # ********* End *********#

    except Exception as e:

        # ********* Begin *********#
        # 输出超时丢包的反馈信息。
        print(f'Sequence {i}: Request timed out')
        # ********* End *********#

    i = i + 1

#********* Begin *********#
# 关闭该UDP套接字
s.close()
#********* End *********#

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值