总结

使用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

相关文章: