Python网络编程(三)-基于tcp协议实现文件传输(解决传输大文件过程中,防止出现粘包现象)
server.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#服务端接收 #解决传输大问题可能出现的粘包现象 import json import socket import struct sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.listen() conn,addr = sk.accept() msg_len = conn.recv(4) #struct.unpack结果是个元组,第一个元素才是具体需要的值。可举例子看下 dic_len = struct.unpack('i',msg_len)[0] print(dic_len) msg = conn.recv(dic_len).decode('utf-8') msg = json.loads(msg) print(msg['filename'],msg['filesize']) with open(msg['filename'],mode='wb') as f: #针对大文件,每次传1024字节,真实情况下,tcp socket 会自动优化,可能将1024个字节切分为几个小文件, #真实大小则不一定为1024,默认接受方还是会按照1024进行减1024字节,因此发送大文件可能会出问题 #需要减去的是,每次接受到的字节大小 while msg['filesize'] >0: content = conn.recv(1024) # msg['filesize'] -= 1024 #减1024,在传输数据时候会出问题 # 应减去每次具体收到的字节大小,才会准确 msg['filesize'] -= len(content) # 写入内容到指定文件 f.write(content) conn.close() sk.close()
client.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#客户端发送 # import os import json import socket import struct sk = socket.socket() sk.connect(('127.0.0.1',9000)) #需要发送文件名,文件大小 # abs_path = r'E:\project\testfile' abs_path = r'F:\web\day43\day43-002 内容回顾.mp4' # os.path模块获取文件名 filename = os.path.basename(abs_path) # os.path模块获取文件大小 filesize = os.path.getsize(abs_path) dic = {'filename':filename,'filesize':filesize} # 网编中传输数据,常用的是json类型 str_dic = json.dumps(dic) b_dic = str_dic.encode('utf-8') msg_len = struct.pack('i',len(b_dic)) #发送4个字节 表示字典转换为字节后的长度 sk.send(msg_len) #发送具体的字典数据 sk.send(b_dic) with open(abs_path,mode='rb') as f: #针对大文件 每次发送1024字节,总文件大小减去每次发送的字节大小进行while循环 while filesize > 0: content = f.read( 1024) # filesize -= 1024 filesize -= len(content) sk.send(content) sk.close()
欢迎转载,但要标明出处.否则追究.欢迎大家阅读收藏和评论,会更新很多精粹。