Socket编程:UDP Ping

Socket编程:UDP Ping

使用python采用UDP协议编写一个ping程序,发送一个简单的ping报文给服务器,并确定从客户发送ping报文服务器到接受到pong报文为止的时延,称为往返时延(RTT) 。
因为UDP是一个不可靠的协议,客户发送的分组可能会丢失,为此,客户不能无限期地等待服务器的响应,等待时间至多为1s,否则,打印一条错误信息。

UDP_Pinger_Sever.py

import random
from socket import *
#AF_INET指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6
#SOCK_DGRAM指定了这个Socket的类型是UDP
serverSocket = socket(AF_INET, SOCK_DGRAM)
#用0.0.0.0绑定到所有的网络地址,还可以用127.0.0.1绑定到本机地址
serverSocket.bind(('127.0.0.1',12000))

while True:
	#产生一个0到10之间的随机数
	rand = random.randint(0, 10)
	#从套接口上读取数据,参数为缓冲区大小
	message, address = serverSocket.recvfrom(1024)
	#通过打印我们可以看到UDP客户端socket的端口是不确定,系统随机分配的
	print("收到来自 %s 的报文: (%s)" % (address,message))
	# 把接收到的信息全部转为大写
	print("随机数是: %d" % rand)
	message = message.upper()
	#如果随机数小于4,服务端无应答,客户端就会超时
	if rand < 4:
		continue
	serverSocket.sendto(message, address)

UDP_Pinger_Client.py

import time
from socket import *
serverName = '127.0.0.1' # 主机
serverPort = 12000
# 创建Socket时,AF_INET指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6
# SOCK_DGRAM指定了这个Socket的类型是UDP
# SOCK_STREAM指定使用面向流的TCP协议
clientSocket = socket(AF_INET, SOCK_DGRAM)
clientSocket.settimeout(1) # 设置超时时间为1s
for i in range(0, 10):
	oldTime = time.time()
	sendTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(oldTime))
	# encode()把str转成bytes,传输格式要求
	message = ('package %d,client_local_time:%s' % (i + 1, sendTime)).encode()
	try:
		# 发送数据
		clientSocket.sendto(message, (serverName, serverPort))
		# 1024指定要接收的最大数据量为1kb = 1024 bytes
		# recvfrom是一个系统调用,由用户态转向系统态,从套接口上接收数据,并捕获数据发送源的地址。
		# 如果数据报大于缓冲区,那么缓冲区中只有数据报的前面部分,其他的数据都丢失了,并且recvfrom()函数返回WSAEMSGSIZE错误
		# 如果没有数据待读,那么除非是非阻塞模式,不然的话套接口将一直等待数据的到来,果没有在Timeout = 1s内接收到数据,此时将返回SOCKET_ERROR错误,错误代码是WSAEWOULDBLOCK。用select()或WSAAsynSelect()可以获知何时数据到达
		# UDP的 recvfrom() 和 TCP 的recv()不一样,具体可以看 TCP Ping项目
		modifiedMessage, serverAddress = clientSocket.recvfrom(1024)
		# 计算往返时间
		rtt = time.time() - oldTime
		# decode 把bytes转成str
		modifiedMessage = modifiedMessage.decode("utf-8")
		print('报文 %d 收到来自 %s 的应答: %s,往返时延(RTT) = %fs' % (i+1, serverName,modifiedMessage, rtt))
	except Exception as e:
		print('报文 %d: 的请求超时' % (i+1)) # 处理异常

运行

猜你喜欢

转载自www.cnblogs.com/Weber-security/p/12661681.html