?创作不易,还希望各位大佬支持一下?
👍?点赞,你的认可是我创作的动力!?
???收藏,你的青睐是我努力的方向!
???评论,你的意见是我进步的财富!?
?
本关任务:Ping 客户端程序循环向指定服务器发送消息,接收服务端回传的消息并打印统计信息。
为了完成本关任务,你需要掌握:
客户端程序在创建完套接字后,通过循环向服务器发送消息,然后接收服务器回传的消息,通过计算收到消息及发送消息的时间差,来反映网络的状况。如果超时时间过后还没收到消息,则报出超时异常。
在网络通信中,网络线路中传输的是字节(二进制格式)流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 编码,则解码时要选择和编码时一样的格式,否则会抛出异常。
bytes = str.encode("GBK")
bytes.decode() #默认使用 UTF-8 编码,会抛出以下异常。
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 服务器,然后接收消息,并将收到消息的时间与发送消息的时间差作为消息的延迟时间进行计算,并打印出来。
根据提示,在右侧编辑器代码的Begin
与End
之间补充代码,实现将消息序号及时间发送给服务器,并接收服务器回传的消息,并计算往返时间。如果超过超时时间未收到消息,则在异常处理中打印超时信息。
平台会对你编写的代码进行测试,并打印出成功接收消息的序号及其相应时间或未接收消息的超时信息。
预期输出:
Sequence 1: Request timed out
Sequence 2: Reply from 127.0.0.1 RTT = 0.000s
Sequence 3: Reply from 127.0.0.1 RTT = 0.000s
Sequence 4: Request timed out
Sequence 5: Reply from 127.0.0.1 RTT = 0.000s
Sequence 6: Reply from 127.0.0.1 RTT = 0.000s
Sequence 7: Request timed out
Sequence 8: Request timed out
Sequence 9: Request timed out
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() # 关闭套接字
?