一、socket發送數據基本流程
- 圖示
- 流程解釋
- 上述流程,為基本的收發數據流程,並且使用ack來解決粘包問題,
- 並且,最后通過獲取server發送的“get file success”來給予用戶友好展示
二、實際應用問題:
- 問題表現:
- client已經接收了完成了所有文件數據,但且還處於阻塞狀態,即:收不到"get file success"
- 問題排查:
- 查看 client 端收到的文件,發現 "get file success" 這個消息,被追加在了文件末尾!
- 查看 client 端主要代碼:
with open(file, 'wb') as f1:recv_size = 0while recv_size < file_size:data = self.sk.recv(1024)recv_size += len(data)f1.write(data)
print(self.sk.recv(1024).decode()) # 打印友好信息print('send_file:{} md5_sum:{}'.format(file_size, file_sum), 'recv_file:{} md5_sum:{}'.format(recv_size, md5_sum), sep='\n') # 打印文件md5值
- 原因總結:
- 因為client是通過 sk.recv(1024)來進行接受數據,而1024表示,最多每次接受1024字節,
- 當文件本身所有數據小於1024時候,那么,最后的"get file success"友好信息也會被client一次性接受,表現在data = self.sk.recv(1024)
- 即此時:
- data包涵了文件本身的所有數據+"友好信息"數據,
- 而當代碼走到print(self.sk.recv(1024).decode())時,便會阻塞(實際上server已經將友好信息發送,只不過因為1024的原因,當做了文件本身數據)
- 解決方式:
- 1、更改1024為更小單位,比如recv(10)
- 接收次數變得更多,且若只要是文件,則一定有余數(文件大小 / 10),比如到最后剩余3字節沒有接受完,而 3< 10,所以這3字節還是會和“友好信息”混在一起
- 2、不發送友好信息
- 在client端直接判斷 recv_data_size 和 send_data_size,並計算文件哈希值,來判斷文件是否完整,
- 本就該如此做,即刪掉兩端關於“友好信息”的交互代碼