用clumsy模擬丟包測試socket庫的失敗重傳
阿新 • • 發佈:2018-11-28
用python的socket庫寫了通訊小程式,現在我需要通過軟體模擬出在網路極差的情況下,socket底層解決丟包問題的能力怎麼樣,我一開始想的是分別在linux和windowns下分別測試,後來一想,不管是什麼作業系統,傳送資料包都是埠傳送的,那麼不管是在什麼作業系統下,只要測試軟體能控制埠傳送的資料包,那麼就能模擬出各種丟包情況,因此我在 Windows 平臺下用clumsy 能人工造成不穩定的網路狀況,在寫兩個測試程式,兩個程式通過tcp通道傳輸一張圖片
服務端程式
import socket def tcp_srv(): # 1. 建立socket負責具體通訊,這個socket其實只負責接受對方的請求,真正通訊的是連結後重新建立的socket # 需要用到兩個引數 # AF_INET: 含義同udp一致,使用ipv4協議族 # SOCK_STREAM: 表明是使用的tcp進行通訊 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 繫結埠和地址 # 此地址資訊是一個元祖型別內容,元祖分兩部分,第一部分為字串,代表ip,第二部分為埠,是一個整數,推薦大於10000 addr = ("127.0.0.1", 10086) sock.bind(addr) # 3. 監聽接入的訪問socket sock.listen() while True: # 4. 接受訪問的socket,可以理解接受訪問即建立了一個通訊的連結通路 # accept返回的元祖第一個元素賦值給skt,第二個賦值給addr skt,addr = sock.accept() # 5. 接受對方的傳送內容,利用接收到的socket接收內容 # 50000000代表接收使用的buffersize #msg = skt.receive(500) msg = skt.recv(50000000) # 接受到的是bytes格式內容 # 想得到str格式的,需要進行解碼 with open('E:/test/a.jpg','wb') as f: f.write(msg) # 6. 如果有必要,給對方傳送反饋資訊 skt.send('ok'.encode()) # 7. 關閉連結通路 skt.close() if __name__ == "__main__": print("Starting tcp server.......") tcp_srv() print("Ending tcp server.......")
客戶端程式
import socket import time def tcp_clt(): # 1. 建立通訊socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 連結對方,請求跟對方建立通路 addr = ("127.0.0.1", 10086) sock.connect(addr) # 當中是你的程式 # 3. 傳送內容到對方伺服器 print("建立通道成功,準備傳輸資料") time.sleep(5) #在這裡設定等待時間,是為了有充足的時間開啟clumsy f = open('E:/qq/aaaa.jpg', 'rb') strChar = f.read() start = time.clock() sock.send(strChar) # 4. 接受對方的反饋 rst = sock.recv(500) elapsed = (time.clock() - start) # 5. 關閉連結通路 sock.close() print(elapsed) if __name__ == "__main__": tcp_clt()
一、在不開模擬軟體的情況下,檢視tcp傳輸一張圖片所需的時間
在這種情況下,傳輸一張圖片只需要0.017s
二、用軟體模擬高延遲情況下的傳輸所需要的時間
在延遲高達2000的網路環境下,圖片依然成功傳輸,雖然耗費了很多時間,花費時間4.47s
三、用軟體模擬高丟包率情況下傳輸所需時間,效果如下
在高延遲和高丟包率下,檔案依然成功傳輸,花費時間13.71s
經過上面的測試,我知道了socket庫底層基於tcp/ip協議的失敗重傳機制做的很好,在非常高的延遲和丟包率下,檔案依然能到達,
那麼發散思維,是不是所有基於tcp/ip設計的網路,我們都可以用上面的方法來測試它的效能呢?