summaryrefslogtreecommitdiff
path: root/day4
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2019-04-22 21:00:47 +0400
committerAndrew <saintruler@gmail.com>2019-04-22 21:00:47 +0400
commit7e591a381db30bfcd374ebdffdc058f8bbfd24ed (patch)
tree70ecc2b57b26eda031a6b611d04f1d69885af32d /day4
parentfae0c2ca1055e2c94299d16b12a20e84fbae1845 (diff)
Четвертая задача завершена. Используется не обязательная библиотека tqdm (чтобы было красиво)
Diffstat (limited to 'day4')
-rw-r--r--day4/task4/client.py76
-rw-r--r--day4/task4/server.py10
2 files changed, 55 insertions, 31 deletions
diff --git a/day4/task4/client.py b/day4/task4/client.py
index 33ea084..bc4a40f 100644
--- a/day4/task4/client.py
+++ b/day4/task4/client.py
@@ -4,40 +4,60 @@ import struct
import json
import shelve
+try:
+ from tqdm import tqdm
+ TQDM = True
+except ImportError:
+ print('Для вывода прогресса загрузки файлов установите библиотеку tqdm')
+ TQDM = False
+
def pack_data(data):
encoded = data.encode()
return struct.pack('I', len(encoded)) + encoded
-def prepare_data(data):
+def handle_input(data):
cmd, args = data.split(' ', maxsplit=1)
if cmd == 'get':
- return json.dumps({'method': 'get', 'path': args})
+ make_get_request(args)
elif cmd == 'cp':
paths = args.split()
if len(paths) != 2:
raise ValueError('Неверное количество путей в параметрах.')
- src, dest = args.split()
+
+ src, dest = paths
+
+ # Если файл не присутствует в БД, то предварительно его загружаем
+ status = 0
if src not in db:
- return json.dumps({'method': 'get_cp', 'path': src})
- with open(dest, 'wb') as f:
- f.write(db[src])
+ status = make_get_request(src)
+
+ if status == 0:
+ with open(dest, 'wb') as f:
+ f.write(db[src])
else:
raise ValueError('Команда не распознана')
+def make_get_request(path):
+ packet = pack_data(json.dumps({'method': 'get', 'path': path}))
+ sock.sendall(packet)
+ response = get_response()
+ return handle_response(response)
+
+
def parse_response(data):
return json.loads(data.decode())
-def get_response(connection):
+def get_response():
buffer = b''
while len(buffer) < DATATYPE_SIZE:
- data = connection.recv(DATATYPE_SIZE - len(buffer))
+ data = sock.recv(DATATYPE_SIZE - len(buffer))
if not data:
raise ConnectionError('Connection was closed')
@@ -48,25 +68,31 @@ def get_response(connection):
raise ConnectionError('Connection was closed')
(size,) = struct.unpack('I', size_packed)
- data = connection.recv(size - len(buffer))
+ data = sock.recv(size - len(buffer))
return parse_response(buffer + data)
-def download_file(filesize, connection):
+def download_file(filesize):
data = b''
- count = 0
- while count < filesize:
- (size,) = struct.unpack('I', connection.recv(DATATYPE_SIZE))
- data += connection.recv(size)
- count += size
+
+ if TQDM:
+ for count in tqdm(range(0, filesize, CHUNK_SIZE)):
+ (size,) = struct.unpack('I', sock.recv(DATATYPE_SIZE))
+ data += sock.recv(size)
+ else:
+ count = 0
+ while count < filesize:
+ (size,) = struct.unpack('I', sock.recv(DATATYPE_SIZE))
+ data += sock.recv(size)
+ count += size
return data
-def handle_response(data, connection):
+def handle_response(data):
if data['status'] == 0:
print(f'Загружаем файл размером {data["size"]} байт...')
- file_data = download_file(data['size'], connection)
+ file_data = download_file(data['size'])
db[data['path']] = file_data
print('Загрузка завершена')
@@ -77,6 +103,8 @@ def handle_response(data, connection):
print('Неизвестная ошибка:')
print(data['reason'])
+ return data['status']
+
def try_connect():
cnt = 0
@@ -101,6 +129,7 @@ def try_connect():
HOST, PORT = ADDR = 'localhost', 6000
DATATYPE_SIZE = 4 # int
+CHUNK_SIZE = 4096000
sock = try_connect()
if sock is None:
@@ -112,20 +141,9 @@ db = shelve.open('backdoor.db')
while True:
try:
data = input('Введите команду:\n')
- data = prepare_data(data)
- if data is None:
- continue
+ handle_input(data)
except KeyboardInterrupt:
break
- except ValueError as err:
- print(err)
-
- else:
- packet = pack_data(data)
- sock.sendall(packet)
- response = get_response(sock)
- handle_response(response, sock)
-
sock.close()
diff --git a/day4/task4/server.py b/day4/task4/server.py
index 980eebc..fb88629 100644
--- a/day4/task4/server.py
+++ b/day4/task4/server.py
@@ -35,18 +35,21 @@ def handle_request(data, connection):
# Я знаю, что это плохо, но сервер не должен падать,
# а других ошибок я не смог вспомнить
except Exception as e:
- header = json.dumps({'status': 2, 'reason': str(e)})
+ header = json.dumps({'status': 2, 'reason': f'{type(e)}: {e}'})
connection.sendall(pack_str(header))
else:
length = len(file_data)
header = json.dumps({'status': 0, 'size': length, 'path': request['path']})
connection.sendall(pack_str(header))
+ print(f'Started sending file of size {length} bytes...')
i = 0
while i < length:
packet = pack_bytes(file_data[i: i + CHUNK_SIZE])
connection.sendall(packet)
i += CHUNK_SIZE
+ print(i / length * 100, '%')
+ print(f'Transmission ended')
def get_data(connection):
@@ -91,7 +94,7 @@ def handle_connection(connection, address):
HOST, PORT = ADDR = '0.0.0.0', 6000
-CHUNK_SIZE = 4096
+CHUNK_SIZE = 4096000
sock = socket.socket()
sock.bind(ADDR)
sock.listen(5)
@@ -103,6 +106,9 @@ while True:
print(f'Got a connection from {address[0]}')
handle_connection(connection, address)
+ except ConnectionResetError:
+ print(f'Connection with {address[0]} was unexpectedly closed')
+
except KeyboardInterrupt:
print('Stopping server...')
sock.close()