Python3利用socket处理文件的传输问题
记录瞬间
最近处理相关的事情时,遇到了需要使用传输文件的方法,网上尽管一搜一大堆,但是还是有一些复杂,最后找到一篇比较简单直接的方法
但是有效果就是好方法
特意记录如下:
Python代码 服务端
import socket,struct host = '0.0.0.0' port = 3000 fmt = '128si' #文件名最长128 i表示文件大小 i的数据类型决定了最大能够传输多大的文件 recv_buffer = 4096 listenSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listenSock.bind((host, port)) while True: listenSock.listen(5) conn, addr = listenSock.accept() headsize = struct.calcsize(fmt) head = conn.recv(headsize) filename = struct.unpack(fmt, head)[0].decode().rstrip('\0') #要删掉用来补齐128个字节的空字符 filename = '/tmp/'+filename filesize = struct.unpack(fmt, head)[1] print("filename:" + filename + "\nfilesize:" + str(filesize)) recved_size = 0 fd = open(filename, 'wb') count = 0 while True: data = conn.recv(recv_buffer) recved_size = recved_size + len(data) #虽然buffer大小是4096,但不一定能收满4096 fd.write(data) if recved_size == filesize: break fd.close() print("new file")
Python代码 客户端
import socket, os, struct host = '接收端IP' port = 3000 fmt = '128si' send_buffer = 4096 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) filepath = input("enter file path:") filename = os.path.split(filepath)[1] filesize = os.path.getsize(filepath) print("filename:" + filename + "\nfilesize:" + str(filesize)) head = struct.pack(fmt, filename.encode(), filesize) print("\nhead size:" + str(head.__len__()) + "\n" + str(head)) sock.sendall(head) restSize = filesize fd = open(filepath,'rb') count = 0 while restSize >= send_buffer: data = fd.read(send_buffer) sock.sendall(data) restSize = restSize - send_buffer print(str(count)+" ") count = count + 1 data = fd.read(restSize) sock.sendall(data) fd.close() print("successfully sent")
其中要注意替换客户端中的ip地址信息
关键的思路是:
1、先要对包的信息(这里是文件名和大小)使用struct模块将其转化为二进制串发送给接收方
2、接收方d根据包信息进行接收
需要注意的是:
1、在不同操作系统下 fmt格式中的数据类型大小可能不同,因此可能会出现两边计算出的headsize不同的情况
2、没有进行异常处理
亲测可用。
++++++++++++++我只是底线++++++++++++++