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、没有进行异常处理
亲测可用。
++++++++++++++我只是底线++++++++++++++
浙公网安备 33010602011771号