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)) # 處理異常

運行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM