UDP Ping程序实现--第5关:客户端向服务器发送消息并接收消息

创作不易,还希望各位大佬支持一下 

👍 点赞,你的认可是我创作的动力! 

⭐️ 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! 

 

任务描述

本关任务:Ping 客户端程序循环向指定服务器发送消息,接收服务端回传的消息并打印统计信息。

相关知识

为了完成本关任务,你需要掌握:

  1. 客户端程序的框架;
  2. 消息内容及编码发送;
  3. 接收消息及解码;
  4. 计算消息的响应时间。
客户端程序结构

客户端程序在创建完套接字后,通过循环向服务器发送消息,然后接收服务器回传的消息,通过计算收到消息及发送消息的时间差,来反映网络的状况。如果超时时间过后还没收到消息,则报出超时异常。

消息编解码

在网络通信中,网络线路中传输的是字节(二进制格式)流bytes。但在我们发送的消息习惯用字符串string来表示,这时就需要用编码encode()和解码decode()函数来转换。

encode()函数:字符串类型(str)提供的方法,用于将字符串类型转换成 bytes 类型,这个过程也称为“编码”。其语法如下: str.encode([encoding="utf-8"][,errors="strict"]) 注意,格式中用 [] 括起来的参数为可选参数,也就是说,在使用此方法时,可以使用 [] 中的参数,也可以不使用。

示例: str.encode() 采用默认的 UTF-8 字符集将 str 编码为字节流 str.encode('GBK') 采用指定的 GBK 字符集将 str 编码为字节流

decode()函数:用于将 bytes 类型的二进制数据转换为 string 类型,这个过程也称为“解码”。其格式如下: bytes.decode([encoding="utf-8"][,errors="strict"]) 示例: bytes.decode() 使用默认的 UTF-8 字符集进行解码为字符串 如果编码时采用的不是默认的 UTF-8 编码,则解码时要选择和编码时一样的格式,否则会抛出异常。

  1. bytes = str.encode("GBK")
  2. bytes.decode() #默认使用 UTF-8 编码,会抛出以下异常。
  3. bytes.decode("GBK") #不会抛出异常
如何发送消息及接受消息

在 UDP 通信中,使用sendto()函数发送 UDP 数据,将数据发送到套接字,输入参数 address 是形式为(host,port)的元组,指定远程地址。返回值是发送的字节数。

接收数据使用recvfrom()函数实现。输入参数为接收缓冲区大小。该函数接收 UDP 数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。

示例如下:

  • 接收数据

msg,addr=udp_server.recvfrom(BUFSIZE)

  • 发送数据

udp_server.sendto(msg,addr)

计算统计信息

在 Ping 客户端程序中,发送消息时将发送消息的序号及发送时间发送到 Ping 服务器,然后接收消息,并将收到消息的时间与发送消息的时间差作为消息的延迟时间进行计算,并打印出来。

编程要求

根据提示,在右侧编辑器代码的BeginEnd之间补充代码,实现将消息序号及时间发送给服务器,并接收服务器回传的消息,并计算往返时间。如果超过超时时间未收到消息,则在异常处理中打印超时信息。

测试说明

平台会对你编写的代码进行测试,并打印出成功接收消息的序号及其相应时间或未接收消息的超时信息。

预期输出:

  1. Sequence 1: Request timed out
  2. Sequence 2: Reply from 127.0.0.1 RTT = 0.000s
  3. Sequence 3: Reply from 127.0.0.1 RTT = 0.000s
  4. Sequence 4: Request timed out
  5. Sequence 5: Reply from 127.0.0.1 RTT = 0.000s
  6. Sequence 6: Reply from 127.0.0.1 RTT = 0.000s
  7. Sequence 7: Request timed out
  8. Sequence 8: Request timed out
  9. Sequence 9: Request timed out
  10. Sequence 10: REquest timed out

代码示例

from socket import *
import time
 
serverName = '127.0.0.1' # 服务器地址,本例中使用本机地址
serverPort = 12000 # 服务器指定的端口
clientSocket = socket(AF_INET, SOCK_DGRAM) # 创建UDP套接字,使用IPv4协议
clientSocket.settimeout(1) # 设置套接字超时值1秒
 
for i in range(0, 9):
    sendTime = time.time()
    message = ('Ping %d %s' % (i+1, sendTime)).encode()     # 生成数据报,编码为bytes以便发送
 
    try:
        ########## Begin ##########
        # 将信息发送到服务器
        clientSocket.sendto(message, (serverName, serverPort))
        # 从服务器接收信息,同时也能得到服务器地址(BUFSIZE为1024)
        modifiedMessage, serverAddress = clientSocket.recvfrom(1024) 
        ########## End ##########
        rtt = time.time() - sendTime # 计算往返时间
 
        print('Sequence %d: Reply from %s    RTT = %.3fs' % (i+1, serverName, rtt)) # 显示信息
    except Exception as e:
        print('Sequence %d: Request timed out.' % (i+1))
 
clientSocket.close() # 关闭套接字

 

  • 36
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值