除此之外,pong报文还需将ping报文中的字符串转为大写。
编写服务器代码,并用随机数模拟丢包情况。
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 12 08:54:58 2024
@author: lenovo
"""
import random
from socket import *
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', 12000))
while True:
message, address = serverSocket.recvfrom(1024)
rand = random.randint(0, 10)
if rand < 4: # 如果随机数小于4,模拟丢包
continue
else: # 否则将消息原样返回给客户端
modifiedMessage = message.decode().upper().encode()
serverSocket.sendto(modifiedMessage, address)
编写客户端代码,用rtt记录往返时间。
from socket import *
import time
serverName = 'serverip' # 服务器的主机名或 IP 地址
serverPort = 12000 # 服务器的端口号
clientSocket = socket(AF_INET, SOCK_DGRAM)
clientSocket.settimeout(1) # 设置超时时间为1秒
for i in range(1, 10):
message = input("what can i say:")
start_time = time.time() # 记录发送时间
clientSocket.sendto(message.encode(), (serverName, serverPort))
try:
modifiedMessage, serverAddress = clientSocket.recvfrom(1024)
end_time = time.time() # 记录接收时间
rtt = end_time - start_time # 计算往返时间
print(f'Received response from {serverName}: {modifiedMessage.decode()}, RTT={rtt:.6f}s')
# 格式化字符串字面值 (f-string),将当前循环的编号 i 和当前时间的 time.time() 值插入到字符串中。
except timeout:
print(f'Timeout: No response from {serverName}')
clientSocket.close()
在两台主机上分别运行服务器和客户端。注意,两台主机应连在同一局域网中,以确保它们能够直接进行通信而无需经过路由器或防火墙等网络设备的干扰。
客户端运行结果:
由此可见,此程序 UDP ping 的丢包率在较高水平。除代码设定外,还可能有以下原因:
-
网络拥塞:网络中可能存在拥塞导致数据包丢失。当网络流量过大,网络设备无法及时处理所有数据包时,就会出现丢包现象。
-
网络抖动:网络抖动是指网络传输延迟和抖动较大,导致数据包在传输过程中出现乱序、延迟等问题,从而可能导致部分数据包丢失。
-
目标主机负载过高:如果目标主机负载过高,无法及时处理接收到的UDP数据包,就会导致丢包情况。
-
防火墙或安全策略:防火墙或安全策略可能会过滤或丢弃某些UDP数据包,导致Ping测试时出现丢包。
-
网络设备故障:网络设备如路由器、交换机等出现故障或性能问题,也可能导致UDP数据包丢失。
-
传输距离过长:UDP对传输延迟要求较高,如果传输距离过长,数据包在传输过程中容易受到干扰和丢失。
-
UDP本身特点:UDP是一种不可靠的传输协议,不提供重传机制,因此即使在网络条件良好的情况下,也有一定概率的丢包。