本文通过socket实现文件上传,需要说明:
1、本例待上传的文件与客户端程序fileupdate_client.py在同一路径下;
2、本例上传到服务端的文件,放在服务端程序fileupdate_server.py同一路径的文件夹'pic'内部。
3、本例上传的命令行格式为“post|filename.jpg”,例如,“ >>>post|thinkpad.jpg ”上传文件名为thinkpad.jpg的文件到服务端。
具体实现如下:
1、服务端程序:fileupdate_server.py
import socket import subprocess import time import os # subprocess.Popen() 重要方法. # 学socket的秘籍:一收一发 sk = socket.socket() host='' #空表示本机,等效于127.0.0.1和localhost port=8000 address = (host,port) sk.bind(address) sk.listen(3) print('waiting......') # conn,addr = sk.accept() #这个conn是客户端的socket对象。非常重要。 buffersize=1024 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) while True: conn, addr = sk.accept() # 这个conn是客户端的socket对象。非常重要。 while True: data = conn.recv(buffersize) cmd,filename,filesize = str(data,'utf8').split('|') #客户端发过来的格式'post|%s|%s|'%(file_name,file_size) path = os.path.join(BASE_DIR,'pic',filename) #join成绝对路径,保存图片 filesize = int(filesize) has_recerve = 0 f=open(path,'ab') while has_recerve!=filesize: data = conn.recv(buffersize) f.write(data) has_recerve += len(data) f.close() conn.close()
2、客户端程序:fileupdate_client.py
import socket import os sk=socket.socket() address = ('127.0.0.1',8000) sk.connect(address) buffersize=1024 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) while True: inp = input('>>>').strip() #格式固定的命令:'post|文件路径',如post|11.jpg cmd_first,cmd_last = inp.split('|') #cmd_last为上传的文件名 print(cmd_last) path = os.path.join(BASE_DIR,cmd_last) #文件绝对路径。#os.path.join()支持跨平台,推荐使用 file_name = os.path.basename(path) #取得文件名,如‘11.jpg’ = cmd_last file_size = os.stat(path).st_size #获取文件大小的方法。 file_info = 'post|%s|%s' %(file_name,file_size) sk.send(bytes(file_info,'utf8')) f = open(path,'rb') has_sent = 0 while has_sent!=file_size: data = f.read(buffersize) #按指定大小从文件中读出数据 sk.sendall(data) has_sent += len(data) # file_size -= buffersize f.close() print('上传成功') sk.close()