计算机网络——自顶向下方法(第七版)Socket Programming Assignment 2:UDPpinger
这部分回顾Socket Programming Assignment 2: UDPpinger。
参考资料:
- https://github.com/jzplp/Computer-Network-A-Top-Down-Approach-Answer/blob/master/Chapter-2
- https://github.com/moranzcw/Computer-Networking-A-Top-Down-Approach-NOTES
简介
此次作业的目的是熟悉UDP套接字编程,实现Pinger程序,主要任务如下:
- 实现基本的Pinger客户端
- 实现增强的Pinger客户端
- 实现Heartbeat客户端与服务器
文件路径结构如下:
Socket2_UDPpinger/
|-- UDPHeartbeatClient.py
|-- UDPHeartbeatServer.py
|-- UDPPingerServer.py
|-- client.py
`-- client_enhance.py
文件解释如下:
- UDPPingerServer.py:Pinger服务器,无需实现;
- client.py:基本的Pinger客户端;
- client_enhance.py:增强的Pinger客户端;
- UDPHeartbeatClient.py, UDPHeartbeatServer.py:Heartbeat客户端与服务器
基本的Pinger客户端
客户端client.py的参数为模拟次数,代码如下:
from socket import *
import time
import sys
def ping(message, clientSocket, serverName, serverPort):
start = time.time()
try:
clientSocket.sendto(message.encode(), (serverName, serverPort))
rawdata, serverAddress = clientSocket.recvfrom(2048)
end = time.time()
data = rawdata.decode()
if len(data) == 0:
return -1
else:
return end - start
except:
return -1
def main():
n = int(sys.argv[1])
serverName = "localhost"
serverPort = 12000
# setdefaulttimeout(1)
clientSocket = socket(AF_INET, SOCK_DGRAM)
# 设置延迟上限
clientSocket.settimeout(1)
message = "test"
for i in range(1, n + 1):
response_time = ping(message, clientSocket, serverName, serverPort)
if (response_time < 0):
print(f"Pint {i} Request timed out")
else:
print(f"Ping {i} {response_time}")
clientSocket.close()
if __name__ == '__main__':
main()
启动服务器以及客户端:
python UDPPingerServer.py
python client.py 10
实验结果:
Ping 1 0.010045766830444336
Ping 2 0.0019996166229248047
Ping 3 0.0015840530395507812
Ping 4 0.002002239227294922
Ping 5 0.0010035037994384766
Ping 6 0.0019953250885009766
Pint 7 Request timed out
Ping 8 0.0010006427764892578
Pint 9 Request timed out
Ping 10 0.0010013580322265625
增强的Pinger客户端
client_enhance.py增加一些统计功能,代码如下:
from socket import *
import time
import sys
def ping(message, clientSocket, serverName, serverPort):
start = time.time()
try:
clientSocket.sendto(message.encode(), (serverName, serverPort))
rawdata, serverAddress = clientSocket.recvfrom(2048)
end = time.time()
data = rawdata.decode()
if len(data) == 0:
return -1
else:
return end - start
except:
return -1
def main():
n = int(sys.argv[1])
serverName = "localhost"
serverPort = 12000
# setdefaulttimeout(1)
clientSocket = socket(AF_INET, SOCK_DGRAM)
clientSocket.settimeout(1)
message = "test"
# stat data
min_time = 100
max_time = 0
all_rtt = 0
sucess_time = 0
for i in range(1, n + 1):
response_time = ping(message, clientSocket, serverName, serverPort)
if (response_time < 0):
print(f"Pint {i} Request timed out")
else:
print(f"Ping {i} {response_time}")
min_time = min(response_time, min_time)
max_time = max(response_time, max_time)
all_rtt += response_time
sucess_time += 1
clientSocket.close()
print(f"Min rtt is {min_time}.")
print(f"Max rtt is {max_time}.")
print(f"Mean rtt is {all_rtt / sucess_time}.")
print(f"Loss rate is {1 - sucess_time / n}")
if __name__ == '__main__':
main()
启动服务器以及客户端:
python UDPPingerServer.py
python client_enhance.py 10
实验结果:
Ping 1 0.0046536922454833984
Ping 2 0.004335165023803711
Ping 3 0.001005411148071289
Pint 4 Request timed out
Ping 5 0.0009920597076416016
Ping 6 0.0010023117065429688
Ping 7 0.0009989738464355469
Pint 8 Request timed out
Ping 9 0.0020017623901367188
Ping 10 0.0009965896606445312
Min rtt is 0.0009920597076416016.
Max rtt is 0.0046536922454833984.
Mean rtt is 0.0019982457160949707.
Loss rate is 0.19999999999999996
Heartbeat客户端与服务器
服务器
使用try, except来判断客户端是否运行,UDPHeartbeatServer.py代码如下:
# UDPHeartbeatServer.py
# We will need the following module to generate randomized lost packets import random
from socket import *
import time
# Create a UDP socket
# Notice the use of SOCK_DGRAM for UDP packets
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.settimeout(20)
# Assign IP address and port number to socket
serverSocket.bind(('', 12000))
while True:
# Receive the client packet along with the address it is coming from
try:
message, address = serverSocket.recvfrom(1024)
except:
print("Client is stop!")
break
end_time = time.time()
if (len(message) == 0):
print("Message loss!")
continue
proc_message = message.decode().split()
number = proc_message[0]
start_time = float(proc_message[1])
diff_time = end_time - start_time
print(f"Number is {number}, time difference is {diff_time}")
serverSocket.close()
客户端
UDPHeartbeatClient.py的参数为模拟次数,代码如下:
from socket import *
import time
import sys
import random
import time
def main():
n = int(sys.argv[1])
serverName = "localhost"
serverPort = 12000
# setdefaulttimeout(1)
clientSocket = socket(AF_INET, SOCK_DGRAM)
for i in range(n):
message = f"{random.random()} {time.time()}"
clientSocket.sendto(message.encode(), (serverName, serverPort))
if __name__ == '__main__':
main()
实验
启动服务器以及客户端:
python UDPHeartbeatServer.py
python UDPHeartbeatClient.py 10
实验结果如下(服务器):
Number is 0.9437354115592858, time difference is 0.009946107864379883
Number is 0.9912950642511882, time difference is 0.004694700241088867
Number is 0.9050499296678337, time difference is 0.001194000244140625
Number is 0.037575470500414654, time difference is 0.00034427642822265625
Number is 0.6443998739965965, time difference is 0.0010006427764892578
Number is 0.7365591696001208, time difference is 0.0010039806365966797
Number is 0.671174745360197, time difference is 0.0009975433349609375
Number is 0.3638988163490168, time difference is 0.0
Number is 0.947734778694654, time difference is 0.000997781753540039
Number is 0.7965422860215524, time difference is 0.001001596450805664
Client is stop!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere