FTP上传文件服务器python实现

总结

使用Python的socket和socketserver模块实现ftp文件服务器。不是很难,但在粘包的问题上纠缠了不少时间。解决办法是发送文件信息之后等待一段时间。

 

 1 #!/usr/bin/python
 2 #coding:utf-8
 3 '''
 4 ftp文件上传 服务器端
 5 '''
 6 
 7 import socketserver
 8 import os
 9 
10 
11 class myFtpServer(socketserver.BaseRequestHandler):
12     def setup(self):
13         pass
14 
15     def handle(self):
16         dir = r'F:\temp' #存放接收文件的目录
17 
18         print('Connected %s:%d' %self.client_address)
19         while True: #持续接收文件
20             #接收文件的名称和大小
21             fileInfo = self.request.recv(1024)
22             if fileInfo.decode('utf-8') == 'exit':
23                 break
24             filename, filesize = fileInfo.decode('utf-8').strip().split('|')
25             filePath = os.path.join(dir, filename) #创建文件存放路径
26             print('Receiving file:%s, filesize:%s'%(filename, filesize))
27             with open(filePath, 'wb') as f:
28                 recvsize = 0
29                 while True: #持续接收文件内容
30                     if recvsize == int(filesize): #当接收的大小与文件大小相等时结束接收
31                         break 
32                     self.data = self.request.recv(1024)
33                     recvsize += len(self.data)
34                     f.write(self.data)
35                 print('upload succeed!!')
36                 print(recvsize)
37         print('Disconnected %s:%d.' %self.client_address)
38     '''
39     def handle(self):
40         base_path = ''
41         conn = self.request
42         print( 'connected...')
43         while True:
44             pre_data = conn.recv(1024)
45             #获取请求方法、文件名、文件大小
46             file_name,file_size = pre_data.decode('utf-8').split('|')
47             
48             #已经接收文件的大小
49             recv_size = 0
50             #上传文件路径拼接
51             file_dir = os.path.join(base_path,file_name)
52             f = open(file_dir,'wb')
53             Flag = True
54             while Flag:
55                 #未上传完毕,
56                 if int(file_size)>recv_size:
57                     #最多接收1024,可能接收的小于1024
58                     data = conn.recv(1024) 
59                     recv_size+=len(data)
60                 #上传完毕,则退出循环
61                 else:
62                     recv_size = 0
63                     Flag = False
64                 #写入文件
65                 f.write(data)
66             print('upload successed.')
67             f.close()            
68     def finish(self):
69         pass
70     
71     '''
72 if __name__ == '__main__':
73     addr = ('127.0.0.1', 9999)
74     sk = socketserver.ThreadingTCPServer(addr, myFtpServer)
75     sk.serve_forever()
View Code

 

 

 

 1 #!/usr/bin/python
 2 #coding:utf-8
 3 '''
 4 ftp文件上传 客户端
 5 '''
 6 import socket
 7 import sys
 8 import os
 9 import time
10 
11 def ftp(address):
12     sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
13     sk.connect(address)
14     while True:
15         #filePath = r'C:\Users\admin\Desktop\test'
16         filePath = input('Input file path:')
17         if filePath == 'exit': #判断退出
18             sk.send(b'exit')
19             break
20         if not os.path.isfile(filePath): #判断是否文件
21             print('Not available file path...')
22             continue
23         filename = os.path.basename(filePath)
24         #dir = os.path.dirname(filePath)
25         
26         filesize = os.stat(filePath).st_size #获取文件大小
27         fileInfo = '%s|%s'%(filename, filesize) #重新组织文件信息,包括文件名和文件大小,用‘|’分割
28         
29         #发送文件信息
30         sk.send(fileInfo.encode(encoding='utf-8', errors='strict'))
31         time.sleep(0.01) #为了防止粘包,在文件信息发送之后等待0.01秒
32         
33         #持续发送文件内容
34         with open(filePath, 'rb') as f:
35             sendsize = 0
36             flag = True
37             while flag:
38                 if sendsize + 1024 > filesize: #判断最后一份文件内容的读取
39                     data = f.read(filesize - sendsize)
40                     flag = False
41                 else: #一般文件内容的读取
42                     data = f.read(1024)
43                     sendsize += 1024
44                 sk.send(data)
45     
46     sk.close()
47 
48 if __name__ == '__main__':
49     addr = ('127.0.0.1',9999)
50     ftp(addr)
View Code

环境:python3.5 win10 x64

posted @ 2017-03-17 15:19  zhangjpn  阅读(432)  评论(0编辑  收藏  举报