SELECT版FTP

SELECT版FTP:
使用SELECT或SELECTORS模块实现并发简单版FTP
允许多用户并发上传下载文件

 

 

  1 import json
  2 import select
  3 import socket
  4 import queue
  5 import os,sys
  6 
  7 
  8 # os.chdir(os.pardir)
  9 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 10 print(BASE_DIR)
 11 msg_data = "%s/data"%BASE_DIR
 12 print(msg_data)
 13 
 14 server = socket.socket()
 15 server_addr = ("localhost",1000)
 16 server.bind(server_addr)
 17 server.listen(7)
 18 inputs = [server,]
 19 outputs = []
 20 message_queue ={}
 21 
 22 while True:
 23     readable,writeable,exeptional = select.select(inputs,outputs,inputs)
 24     # 存放所有的活动
 25     for sock in readable:
 26         if sock is server:
 27             conn, client_addr = sock.accept()
 28             inputs.append(conn)
 29             message_queue[conn] = queue.Queue()    #为防阻塞,先把信息存入队列
 30         else:
 31             data = sock.recv(1024)
 32             if data:
 33                 message_queue[sock].put(data)
 34                 if sock not in outputs:
 35                     outputs.append(sock)
 36             else:
 37                 if sock in outputs:
 38                     outputs.remove(sock)
 39                 inputs.remove(sock)
 40                 del message_queue[sock]
 41     #
 42     # 存放连接信息
 43     #
 44     for sock in writeable:
 45         try:
 46             cmd = message_queue[sock].get_nowait()
 47         except queue.Empty:
 48             outputs.remove(sock)
 49         else:
 50             print("recv data:", cmd)
 51             data = json.loads(cmd.decode())
 52             if data.get('action') is not None:
 53                 #
 54                 # 上传文件
 55                 if data['action'] == 'put':
 56                     # client sends file to server
 57                     filename = "%s/%s" % (msg_data,data['filename'])
 58                     file_obj = open(filename, 'wb')
 59                     received_size = 0
 60                     sock.send(b'1')
 61                     while True:
 62                         if received_size == data['size']:
 63                             break
 64                         recv_data = sock.recv(1024)
 65                         file_obj.write(recv_data)
 66                         received_size += len(recv_data)
 67                     if received_size == data['size']:
 68                         print('Successfully received file ', data['filename'])
 69                     file_obj.close()
 70                 #
 71                 # 下载文件
 72                 elif data['action'] == 'get':
 73                     filename = "%s/%s" % (msg_data, data['filename'])
 74                     print(filename)
 75 
 76                     if os.path.isfile(filename):
 77                         data['file_size'] = os.path.getsize(filename)
 78                         data['ERROR'] = '0'
 79                     else:
 80                         data['ERROR'] = '777'      #ERROR标识
 81                     sock.send(json.dumps(data).encode())
 82                     if os.path.isfile(filename):
 83                         if sock.recv(1) == b'1':         #等待客户端响应,防粘包
 84                             if data['ERROR'] == '0':
 85                                 file_obj = open(filename, 'rb')
 86                                 for line in file_obj:
 87                                     sock.send(line)
 88                 #
 89                 # 其他命令
 90                 else:
 91                     data['cmd'] = data['cmd'].upper()
 92                     sock.send(json.dumps(data).encode())
 93 
 94     #
 95     # 错误链接
 96     for sock in exeptional:
 97         if sock in outputs:
 98             outputs.remove(sock)
 99         inputs.remove(sock)
100         del message_queue[sock]
server.py
 1 import json
 2 import socket
 3 import os
 4 
 5 # os.chdir(os.pardir)
 6 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 7 print(BASE_DIR)
 8 msg_data = "%s/data"%BASE_DIR
 9 print(msg_data)
10 
11 server_address = ('localhost', 1000)
12 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
13 sock.connect(server_address)
14 print('''------Welcome!!-----
15                         (helps:帮助信息)''')
16 while True:
17     cmd = input(">>>").strip()
18     cmd_list = cmd.split()
19     #
20     #上传文件
21     if cmd_list[0] == 'put':
22         if len(cmd_list) == 1:   #命令不能识别
23             print('No filename follows after put cmd!')
24             continue
25         filename = "%s/%s" % (msg_data, cmd_list[1])#将所有的文件都归入data文件夹
26         # print(filename)
27         if os.path.isfile(filename):
28             file_obj = open(filename,'rb')
29             base_filename = filename.split('/')[-1]
30             data_header = {
31                 'action':'put',
32                 'filename':base_filename,
33                 'size':os.path.getsize(filename)
34             }
35             sock.send(json.dumps(data_header).encode())
36             if sock.recv(1) == b'1':      #防止粘包
37                 for line in file_obj:
38                     sock.send(line)
39                 file_obj.close()
40                 print('put all file..')
41         else:
42             print('File is not valid')
43             continue
44     #
45     # 下载文件
46     elif cmd_list[0] == 'get':
47         if len(cmd_list) == 1:
48             print('No filename follows after get cmd!')
49             continue
50         file_dir = "%s/%s" %(msg_data,cmd_list[1])
51         filename= file_dir.split("/")[-1]
52 
53         data_header = {
54             'action':'get',
55             'filename':filename,
56             'ERROR':'0'
57         }
58         sock.send(json.dumps(data_header).encode())
59         data_header = json.loads(sock.recv(1024).decode())
60         if data_header['ERROR'] == '0':
61             file_obj = open(data_header['filename'], 'wb')
62             received_size = 0
63             sock.send(b'1')
64             while True:
65 
66                 if received_size == data_header['file_size']:
67                     break
68                 recv_data = sock.recv(1024)
69                 file_obj.write(recv_data)
70                 received_size += len(recv_data)
71 
72             print('Successfully received file ', data_header['filename'])
73             file_obj.close()
74     #
75     # 帮助信息
76     elif cmd_list[0] == 'helps':
77         print('''
78         put 文件名         #上传文件
79         get 文件名         #下载文件
80         ''')
81     #
82     # 其他命令
83     else:
84         data_header = {
85             'action':'else',
86             'cmd':cmd
87         }
88         sock.send(json.dumps(data_header).encode())
89         data_recv = json.loads(sock.recv(1024).decode())
90         print(data_recv['cmd'])
client.py

 

转载于:https://www.cnblogs.com/garrett0220/articles/8116756.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值