python------Socket網路程式設計(二)粘包問題
阿新 • • 發佈:2018-11-02
一.socket網路程式設計
粘包:服務端兩次傳送指令在一起,它會把兩次傳送內容合在一起傳送,稱為粘包,從而出現錯誤。
解決方法:(比較low的方法)
有些需要實時更新的,用sleep有延遲,不能這樣解決問題。
解決方法之高階方法:
客戶端:
二.傳送檔案
ftp server端有哪幾步呢?
①讀取客戶端發過來的檔名
②檢測檔案是否存在
③開啟檔案
④檢測檔案大小
⑤傳送檔案大小給客戶端
⑥等待客戶端確認
⑦開始邊讀邊發資料
⑧傳送md5
1 import socket 2 import os 3 import time4 import hashlib 5 server = socket.socket() 6 server.bind(('localhost',3333)) 7 8 server.listen() 9 10 while True: 11 conn,addr = server.accept() 12 print("new conn:",addr) 13 while True: 14 print("等待新指令") 15 data = conn.recv(1024) 16 if not data: 17 print("客戶端已斷開") 18 break 19 cmd,filename = data.decode().split() 20 print(filename) 21 if os.path.isfile(filename): 22 f = open(filename,"rb") 23 m = hashlib.md5() 24 file_size = os.stat(filename).st_size #在os模組中獲取檔案大小 25 conn.send(str(file_size).encode()) #傳送檔案大小 26 conn.recv(1024) #wait for ack 27 for line in f: 28 m.update(line) 29 conn.send(line) 30 print("file md5",m.hexdigest()) 31 f.close() 32 conn.send(m.hexdigest().encode()) #send md5 33 34 print("執行指令:", data) 35 36 server.close()
客戶端:
1 import socket 2 import hashlib 3 client = socket.socket() 4 client.connect(('localhost',3333)) 5 6 while True: 7 cmd = input(">>:").strip() #cmd = input(b">>:").strip()如果前面直接加b,則只能傳英文 8 if len(cmd) == 0 : continue 9 if cmd.startswith("get"): 10 client.send(cmd.encode()) 11 server_response = client.recv(1024) 12 print("server response:",server_response) 13 client.send("ready to recv file".encode()) 14 file_total_size = int(server_response.decode()) 15 received_size = 0 16 filename = cmd.split()[1] 17 f = open("wenjian","wb") 18 m = hashlib.md5() 19 20 while received_size<file_total_size: 21 #下面這段程式碼徹底解決粘包問題 22 if file_total_size - received_size > 1024: #要收不止一次 23 size = 1024 24 else: 25 size = file_total_size - received_size #最後一次了,剩多少收多少 26 print("last receive:",size) 27 28 data = client.recv(1024) 29 received_size += len(data) 30 m.update(data) 31 f.write(data) 32 print(file_total_size,received_size) #看演示效果 33 else: 34 new_file_md5 = m.hexdigest() 35 print("file received done",received_size,file_total_size) 36 f.close() 37 server_file_md5 = client.recv(1024) 38 print("server file md5:",server_file_md5) 39 print("client file md5:", new_file_md5) 40 41 42 client.close()
具體用的時候在鑽研吧。