FTP上传文件服务器python实现
2024-08-29 09:06:59
总结
使用Python的socket和socketserver模块实现ftp文件服务器。不是很难,但在粘包的问题上纠缠了不少时间。解决办法是发送文件信息之后等待一段时间。
#!/usr/bin/python
#coding:utf-8
'''
ftp文件上传 服务器端
''' import socketserver
import os class myFtpServer(socketserver.BaseRequestHandler):
def setup(self):
pass def handle(self):
dir = r'F:\temp' #存放接收文件的目录 print('Connected %s:%d' %self.client_address)
while True: #持续接收文件
#接收文件的名称和大小
fileInfo = self.request.recv(1024)
if fileInfo.decode('utf-8') == 'exit':
break
filename, filesize = fileInfo.decode('utf-8').strip().split('|')
filePath = os.path.join(dir, filename) #创建文件存放路径
print('Receiving file:%s, filesize:%s'%(filename, filesize))
with open(filePath, 'wb') as f:
recvsize = 0
while True: #持续接收文件内容
if recvsize == int(filesize): #当接收的大小与文件大小相等时结束接收
break
self.data = self.request.recv(1024)
recvsize += len(self.data)
f.write(self.data)
print('upload succeed!!')
print(recvsize)
print('Disconnected %s:%d.' %self.client_address)
'''
def handle(self):
base_path = ''
conn = self.request
print( 'connected...')
while True:
pre_data = conn.recv(1024)
#获取请求方法、文件名、文件大小
file_name,file_size = pre_data.decode('utf-8').split('|') #已经接收文件的大小
recv_size = 0
#上传文件路径拼接
file_dir = os.path.join(base_path,file_name)
f = open(file_dir,'wb')
Flag = True
while Flag:
#未上传完毕,
if int(file_size)>recv_size:
#最多接收1024,可能接收的小于1024
data = conn.recv(1024)
recv_size+=len(data)
#上传完毕,则退出循环
else:
recv_size = 0
Flag = False
#写入文件
f.write(data)
print('upload successed.')
f.close()
def finish(self):
pass '''
if __name__ == '__main__':
addr = ('127.0.0.1', 9999)
sk = socketserver.ThreadingTCPServer(addr, myFtpServer)
sk.serve_forever()
#!/usr/bin/python
#coding:utf-8
'''
ftp文件上传 客户端
'''
import socket
import sys
import os
import time def ftp(address):
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sk.connect(address)
while True:
#filePath = r'C:\Users\admin\Desktop\test'
filePath = input('Input file path:')
if filePath == 'exit': #判断退出
sk.send(b'exit')
break
if not os.path.isfile(filePath): #判断是否文件
print('Not available file path...')
continue
filename = os.path.basename(filePath)
#dir = os.path.dirname(filePath) filesize = os.stat(filePath).st_size #获取文件大小
fileInfo = '%s|%s'%(filename, filesize) #重新组织文件信息,包括文件名和文件大小,用‘|’分割 #发送文件信息
sk.send(fileInfo.encode(encoding='utf-8', errors='strict'))
time.sleep(0.01) #为了防止粘包,在文件信息发送之后等待0.01秒 #持续发送文件内容
with open(filePath, 'rb') as f:
sendsize = 0
flag = True
while flag:
if sendsize + 1024 > filesize: #判断最后一份文件内容的读取
data = f.read(filesize - sendsize)
flag = False
else: #一般文件内容的读取
data = f.read(1024)
sendsize += 1024
sk.send(data) sk.close() if __name__ == '__main__':
addr = ('127.0.0.1',9999)
ftp(addr)
环境:python3.5 win10 x64
最新文章
- 小白解决CENTOS7错误:Cannot find a valid baseurl for repo: base/7/x86_6
- 恢复 混淆后的 stacktrace 文件
- Linux常用命令笔记一
- Oracle中的数据分页
- LA 4255 (拓扑排序 并查集) Guess
- JSON Date Format/JSON 日期格式方法分享
- 学习嵌入式Linux有没有一个最佳的顺序(持续更新)
- Hive和Jdbc示例
- 内置函数:filter函数
- logback配置信息
- Python从入门到放弃Day01
- javaweb 与jsp页面的交互流程 (初次接触时写)
- ensp 单臂路由实验
- Entity Framework Code first(转载)
- RGB ECT 4BIT 压缩后质量远高于RGB ETC2 4BIT
- visual studio 2017使用技巧
- learning at command AT+CEREG
- Windows下利用TortoiseSVN搭建本地SVN服务器
- mysql中各种join连表查询总结
- Java系列:JVM中的OopMap(zz)