TCP发送大文件到指定目录(图片,文件,视频)
使用TCP实现大型文件的传输
-
可能会出现的问题
- 粘包,数据不完整
-
解决方法:
- 使用struct 模块,设置每次收取内容具体字节,从上到下依次取出
- 在从文件中读取数据进行传输的时候使用while 循环,每次取1024字节, 同样每次也传1024字节(原因:如果传入的文件过大tcp会自动进行拆包导致一些数据不能及时到达,从而recv和send数据大小的不同,所以需要多次调用)
-
服务端
# server import socket import struct import os import json FILE_PATH=r'C:\Users\Administrator\Desktop\bao\文件' sk=socket.socket() sk.bind(('192.168.0.103',1235)) sk.listen() while True: conn,addr=sk.accept() while True: msg1 = conn.recv(4) s=struct.unpack('i',msg1)[0] print(s) msg=conn.recv(s) msg=json.loads(msg) print(msg) with open(os.path.join(FILE_PATH,msg['filename']),mode='wb')as f: while msg['filesize']>0: content=conn.recv(1024) msg['filesize']-=len(content) f.write(content)
-
客户端
#client import socket import struct import os import json FILE_PATH=r'C:\Users\baobao\Desktop\笔记\笔记' sk=socket.socket() sk.connect(('192.168.0.103',1235)) while True: alist=[] s_list = os.walk(FILE_PATH, topdown=True, onerror=None, followlinks=False) for a, b, c in s_list: for i in c: path = os.path.join(a, i) alist.append(path) for index,i in enumerate(alist,1): print(index,os.path.basename(i)) ret=input('请输入传输内容的序号:') if ret.upper()=='Q':break filename=os.path.basename(alist[int(ret)-1]) filesize=os.path.getsize(alist[int(ret)-1]) dic={'filename':filename,'filesize':filesize} dic=json.dumps(dic).encode('utf-8') s_si = struct.pack('i', len(dic)) sk.send(s_si) sk.send(dic) with open(alist[int(ret)-1],mode='rb')as f: while filesize>0: content=f.read(1024) filesize-=len(content) sk.send(content) sk.close()