From bcf4cac74e4cc5d1fc85b789ee22c089f6986fae Mon Sep 17 00:00:00 2001 From: PAND-or Date: Sat, 23 Mar 2019 14:03:02 +0300 Subject: [PATCH 1/4] lesson07 --- client/__main__.py | 119 +++++++++++++++++++++++-------------- log/client.log | 23 +++++++ log/server.log | 37 ++++++++++++ server/__main__.py | 70 +++++++++++----------- server/authentication.py | 21 +++++++ server/customlogging.py | 49 +++++++++++++++ server/handlers.py | 27 +++++++++ server/text/controllers.py | 9 +++ 8 files changed, 276 insertions(+), 79 deletions(-) create mode 100644 server/authentication.py create mode 100644 server/customlogging.py create mode 100644 server/handlers.py diff --git a/client/__main__.py b/client/__main__.py index bc7c8bc..3970dba 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -21,6 +21,7 @@ import argparse import socket import json +import hashlib from datetime import datetime from client_log_config import logger @@ -29,6 +30,7 @@ def createParser(): parser = argparse.ArgumentParser() parser.add_argument('host', nargs='?', default='localhost') parser.add_argument('port', nargs='?', default='7777') + parser.add_argument('-m', '--mode', nargs='?', type=str, default='w') return parser @@ -38,55 +40,84 @@ def createParser(): port = int(re.search('[0-9]{2,}', args.port).group(0)) - -sock = socket.socket() try: + sock = socket.socket() sock.connect((args.host, port)) - # сформировать presence-сообщение; - # В формате JIM - - msg_presence = json.dumps( - { - "action": "presence", - "time": datetime.now().timestamp(), - "type": "status", - "user": { - "account_name": input("Enter user Name: "), - "status": input("Status message: ") - } - } - ) - """ - msg_action = json.dumps( - { - "action": input("Enter action (lower_text): "), - "data": input("Enter data: ") - } - ) - #sock.send(msg_action.encode()) - """ - - # отправить сообщение серверу; - sock.send(msg_presence.encode()) - - - # получить ответ сервера; - data = sock.recv(1024) - response = json.loads( - data.decode('utf-8') - ) - # разобрать сообщение сервера; - - if response.get('response') == 200: - if response.get('alert'): - logger.debug(f"Response Message: {response.get('alert')}") - print( - f"Response Message: {response.get('alert')}" + if args.mode == 'w': + while True: + # сформировать presence-сообщение; + # В формате JIM + + hash_obj = hashlib.sha1() + hash_obj.update(b'secret_key') + + msg_presence = json.dumps( + { + "action": "presence", + "time": datetime.now().timestamp(), + "type": "status", + "user": { + "account_name": input("Enter user Name: "), + "status": input("Status message: ") + } + } ) - else: - logger.critical(f"Error request: {response.get('error')}") + # отправить сообщение серверу; + sock.send(msg_presence.encode()) + """ + msg_action = json.dumps( + { + "action": input("Enter action (lower_text): "), + "data": input("Enter data: ") + } + ) + + sock.send(msg_action.encode()) + """ + while True: + # получить ответ сервера; + data = sock.recv(1024) + response = json.loads( + data.decode('utf-8') + ) + # разобрать сообщение сервера; + + if response.get('response') == 200: + if response.get('alert'): + logger.debug(f"Response Message: {response.get('alert')}") + print( + f"Response Message: {response.get('alert')}" + ) + sock.close() + break + else: + logger.critical(f"Error request: {response.get('error')}") + else: + while True: + # получить ответ сервера; + data = sock.recv(1024) + response = json.loads( + data.decode('utf-8') + ) + # разобрать сообщение сервера; + + if response.get('response') == 200: + if response.get('alert'): + logger.debug(f"Response Message: {response.get('alert')}") + print( + f"Response Message: {response.get('alert')}" + ) + sock.close() + break + else: + logger.critical(f"Error request: {response.get('error')}") + + #sock.close() +except KeyboardInterrupt: + logger.info(f"client closed") sock.close() + except Exception: logger.critical(f'client cant conntect to host:{args.host} port{port}') diff --git a/log/client.log b/log/client.log index 7461fbb..d8a4c53 100644 --- a/log/client.log +++ b/log/client.log @@ -1,3 +1,26 @@ 2019-03-22 23:36:02,696 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 2019-03-22 23:36:10,249 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 2019-03-22 23:36:23,476 - DEBUG - client - __main__ - Response Message: Hi Vasya +2019-03-23 11:25:04,037 - DEBUG - client - __main__ - Response Message: Hi Ggg +2019-03-23 11:25:11,259 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 11:25:22,627 - DEBUG - client - __main__ - Response Message: Hi gfd +2019-03-23 11:25:30,862 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 11:25:40,404 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:13:24,608 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:14:04,399 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:16:05,126 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:18:41,129 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:19:35,400 - DEBUG - client - __main__ - Response Message: Hi gfdgfd +2019-03-23 12:20:32,307 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:21:07,810 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:21:47,540 - CRITICAL - client - __main__ - Error request: Wrong request format +2019-03-23 12:22:47,865 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:23:13,817 - CRITICAL - client - __main__ - Error request: Wrong request format +2019-03-23 12:23:32,678 - CRITICAL - client - __main__ - Error request: Wrong request format +2019-03-23 12:24:35,061 - DEBUG - client - __main__ - Response Message: Hi gd +2019-03-23 12:48:59,584 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 12:49:09,084 - DEBUG - client - __main__ - Response Message: Hi fds +2019-03-23 12:49:15,536 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 13:23:06,491 - INFO - client - __main__ - client closed +2019-03-23 13:23:06,560 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 +2019-03-23 13:23:06,560 - CRITICAL - client - __main__ - client cant conntect to host:localhost port7777 diff --git a/log/server.log b/log/server.log index 1ddc1a2..04af256 100644 --- a/log/server.log +++ b/log/server.log @@ -2,3 +2,40 @@ 2019-03-22 23:36:17,416 - INFO - __main__ - Client detected ('127.0.0.1', 55376) 2019-03-22 23:36:23,476 - INFO - log - function send_presence() call from __main__ 2019-03-22 23:36:23,476 - INFO - __main__ - client ('127.0.0.1', 55376) closed +2019-03-23 11:08:40,768 - INFO - __main__ - Client detected ('127.0.0.1', 60578) +2019-03-23 11:25:04,036 - INFO - log - function send_presence() call from __main__ +2019-03-23 11:25:04,037 - INFO - __main__ - client ('127.0.0.1', 60578) closed +2019-03-23 11:25:10,396 - INFO - __main__ - client ('127.0.0.1', 60578) closed +2019-03-23 11:25:21,471 - INFO - __main__ - Client detected ('127.0.0.1', 60845) +2019-03-23 11:25:22,626 - INFO - log - function send_presence() call from __main__ +2019-03-23 11:25:22,627 - INFO - __main__ - client ('127.0.0.1', 60845) closed +2019-03-23 11:25:29,652 - INFO - __main__ - client ('127.0.0.1', 60845) closed +2019-03-23 12:13:21,472 - INFO - __main__ - Client detected ('127.0.0.1', 61483) +2019-03-23 12:14:01,870 - INFO - __main__ - Client detected ('127.0.0.1', 61505) +2019-03-23 12:16:03,934 - INFO - __main__ - Client detected ('127.0.0.1', 61527) +2019-03-23 12:18:39,648 - INFO - __main__ - Client detected ('127.0.0.1', 61640) +2019-03-23 12:19:33,574 - INFO - __main__ - Client detected ('127.0.0.1', 61656) +2019-03-23 12:19:35,400 - INFO - log - function send_presence() call from __main__ +2019-03-23 12:19:35,400 - INFO - __main__ - client ('127.0.0.1', 61656) closed +2019-03-23 12:20:23,242 - INFO - __main__ - Client detected ('127.0.0.1', 61662) +2019-03-23 12:21:00,099 - INFO - __main__ - Client detected ('127.0.0.1', 61667) +2019-03-23 12:21:38,675 - INFO - __main__ - Client detected ('127.0.0.1', 61672) +2019-03-23 12:21:47,540 - CRITICAL - __main__ - error 400 bad request: {'action': 'lower_text', 'data': 'GGG'} +2019-03-23 12:21:47,540 - INFO - __main__ - client ('127.0.0.1', 61672) closed +2019-03-23 12:22:41,135 - INFO - __main__ - client ('127.0.0.1', 61672) closed +2019-03-23 12:23:07,415 - INFO - __main__ - Client detected ('127.0.0.1', 61688) +2019-03-23 12:23:13,816 - CRITICAL - __main__ - error 400 bad request: {'action': 'lowe_text', 'data': 'FFFF'} +2019-03-23 12:23:13,816 - INFO - __main__ - client ('127.0.0.1', 61688) closed +2019-03-23 12:23:26,904 - INFO - __main__ - Client detected ('127.0.0.1', 61690) +2019-03-23 12:23:32,678 - CRITICAL - __main__ - error 400 bad request: {'action': 'lower_text', 'data': 'GGGG'} +2019-03-23 12:23:32,678 - INFO - __main__ - client ('127.0.0.1', 61690) closed +2019-03-23 12:24:33,255 - INFO - __main__ - Client detected ('127.0.0.1', 61696) +2019-03-23 12:24:35,060 - INFO - log - function send_presence() call from __main__ +2019-03-23 12:24:35,061 - INFO - __main__ - client ('127.0.0.1', 61696) closed +2019-03-23 12:48:58,086 - INFO - __main__ - client ('127.0.0.1', 61696) closed +2019-03-23 12:49:07,582 - INFO - __main__ - Client detected ('127.0.0.1', 61938) +2019-03-23 12:49:09,084 - INFO - log - function send_presence() call from handlers +2019-03-23 12:49:14,361 - INFO - __main__ - client ('127.0.0.1', 61938) closed +2019-03-23 13:20:20,749 - INFO - __main__ - Client detected ('127.0.0.1', 62287) +2019-03-23 13:21:57,519 - INFO - log - function send_presence() call from handlers +2019-03-23 13:21:57,520 - INFO - __main__ - Client detected ('127.0.0.1', 62288) diff --git a/server/__main__.py b/server/__main__.py index e9b7ea7..bb5a47a 100644 --- a/server/__main__.py +++ b/server/__main__.py @@ -2,13 +2,10 @@ __author__ = "Андрей Петров" import sys - - - import json import socket import argparse - +import select @@ -19,6 +16,7 @@ ) from routes import resolve from server_log_config import logger +from handlers import handle_client_request def createParser(): parser = argparse.ArgumentParser() @@ -35,43 +33,45 @@ def createParser(): sock.bind((args.addr, int(args.port))) sock.listen(5) +responses = [] +connections = [] try: while True: # принимает сообщение клиента; client, address = sock.accept() + connections.append(client) + logger.info(f'Client detected {address}') - data = client.recv(1024) - request = json.loads( - data.decode('utf-8') - ) - - if validate_request(request): - controller = resolve(request.get('action')) - if controller: - try: - response = controller(request) - except Exception as err: - logger.critical(err, exc_info=True) - response = make_response( - request, 500, - error='Internal server error.' - ) - else: - logger.critical(f"error 404 controller: {request.get('action')} not found") - response = make_404(request) - else: - response = make_400(request) - logger.critical(f"error 400 bad request: {request}") - - if response.get('code') == 400: - logger.error(f'Bad Request: { action_name } request: { request }') - - response_string = json.dumps(response) - client.send(response_string.encode('utf-8')) - client.close() - logger.info(f"client {address} closed") + rlist, wlist, xlist = select.select(connections, connections, [], 0) + + for client in connections: + if client in rlist: #соеденения на запись + data = client.recv(1024) + request = json.loads( + data.decode('utf-8') + ) + action_name = request.get('action') + response = handle_client_request(request) + + if response.get('code') == 400: + logger.error(f'Bad Request: { action_name } request: { request }') + + if response.get('code') == 200: + responses.append(response) + response_string = json.dumps(response) + client.send(response_string.encode('utf-8')) + + if client in wlist: #соеденения слушатели + if responses: + for conn in wlist: + response_obj_string = json.dumps(responses) + conn.send(response_obj_string.encode('utf-8')) + if client in xlist: + pass + #client.close() + #logger.info(f"client {address} closed") except KeyboardInterrupt: - logger.info(f"client {address} closed") + logger.info(f"server {address} closed") sock.close() diff --git a/server/authentication.py b/server/authentication.py new file mode 100644 index 0000000..d3ce166 --- /dev/null +++ b/server/authentication.py @@ -0,0 +1,21 @@ +from functools import wraps +from protocol import make_response + + +def login_required(func): + @wraps(func) + def wrap(request, *args, **kwrags): + if request.get('user'): + return func(request, *args, **kwrags) + return make_response(request, 403, 'Access denied.') + return wrap + + +class LoginRequired: + def __call__(self, func): + @wraps(func) + def wrap(request, *args, **kwrags): + if request.get('user'): + return func(request, *args, **kwrags) + return make_response(request, 403, 'Access denied.') + return wrap diff --git a/server/customlogging.py b/server/customlogging.py new file mode 100644 index 0000000..7f50af6 --- /dev/null +++ b/server/customlogging.py @@ -0,0 +1,49 @@ +import logging +from functools import wraps + + +logger = logging.getLogger('stack_logger') +handler = logging.StreamHandler() + +formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s - %(message)s') +handler.setFormatter(formatter) +handler.setLevel(logging.DEBUG) +logger.addHandler(handler) +logger.setLevel(logging.DEBUG) + + +def stack_logging(message=''): + + def decorator(func): + @wraps(func) + def wrap(request, *args, **kwrags): + format_mapping = { + 'func_name': func.__name__, + 'request_data': request.get('data') + } + func_call = func(request, *args, **kwrags) + logger.debug( + message % format_mapping, stack_info=True + ) + return func_call + return wrap + return decorator + + +class StackLogging: + def __init__(self, message=''): + self._message = message + + def __call__(self, func): + @wraps(func) + def wrap(request, *args, **kwrags): + format_mapping = { + 'func_name': func.__name__, + 'request_data': request.get('data'), + } + func_call = func(request, *args, **kwrags) + logger.debug( + self._message % format_mapping, stack_info=True + ) + return func_call + return wrap diff --git a/server/handlers.py b/server/handlers.py new file mode 100644 index 0000000..a6d6e3c --- /dev/null +++ b/server/handlers.py @@ -0,0 +1,27 @@ +from protocol import ( + validate_request, make_response, + make_400, make_404 +) +from routes import resolve +from server_log_config import logger + + +def handle_client_request(request): + if validate_request(request): + controller = resolve(request.get('action')) + if controller: + try: + return controller(request) + except Exception as err: + logger.critical(err, exc_info=True) + return make_response( + request, 500, + error='Internal server error.' + ) + else: + logger.critical(f"error 404 controller: {request.get('action')} not found") + return make_404(request) + else: + logger.critical(f"error 400 bad request: {request}") + return make_400(request) + diff --git a/server/text/controllers.py b/server/text/controllers.py index c4cc8b7..0baff3d 100644 --- a/server/text/controllers.py +++ b/server/text/controllers.py @@ -1,8 +1,13 @@ from protocol import make_response, make_400 +from authentication import login_required, LoginRequired from log import log +from customlogging import stack_logging, StackLogging + +@stack_logging('Function %(func_name)s was called.') @log +@login_required def get_upper_text(request): data = request.get('data') if not data: @@ -13,7 +18,11 @@ def get_upper_text(request): data.upper() ) + + +@StackLogging('Request body: %(request_data)s') @log +@LoginRequired() def get_lower_text(request): data = request.get('data') if not data: From 4572eb26516173b6bc46900fc7bafe6f724768c8 Mon Sep 17 00:00:00 2001 From: PAND-or Date: Tue, 26 Mar 2019 14:52:55 +0300 Subject: [PATCH 2/4] ls07 fix --- client/__main__.py | 43 +++++---------------------- server/__main__.py | 73 +++++++++++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 66 deletions(-) diff --git a/client/__main__.py b/client/__main__.py index 3970dba..e4017ad 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -24,6 +24,7 @@ import hashlib from datetime import datetime from client_log_config import logger +import select def createParser(): @@ -75,46 +76,16 @@ def createParser(): sock.send(msg_action.encode()) """ - while True: - # получить ответ сервера; - data = sock.recv(1024) - response = json.loads( - data.decode('utf-8') - ) - # разобрать сообщение сервера; - - if response.get('response') == 200: - if response.get('alert'): - logger.debug(f"Response Message: {response.get('alert')}") - print( - f"Response Message: {response.get('alert')}" - ) - sock.close() - break - else: - logger.critical(f"Error request: {response.get('error')}") else: while True: - # получить ответ сервера; - data = sock.recv(1024) - response = json.loads( - data.decode('utf-8') - ) - # разобрать сообщение сервера; - - if response.get('response') == 200: - if response.get('alert'): - logger.debug(f"Response Message: {response.get('alert')}") - print( - f"Response Message: {response.get('alert')}" - ) - sock.close() - break - else: - logger.critical(f"Error request: {response.get('error')}") + rlist, wlist, xlist = select.select([], [sock], [], 0) - #sock.close() + response = sock.recv(1024) + + if response: + print(response.decode()) + break except KeyboardInterrupt: logger.info(f"client closed") sock.close() diff --git a/server/__main__.py b/server/__main__.py index bb5a47a..868faa4 100644 --- a/server/__main__.py +++ b/server/__main__.py @@ -9,7 +9,6 @@ - from protocol import ( validate_request, make_response, make_400, make_404 @@ -24,6 +23,8 @@ def createParser(): parser.add_argument('-p', '--port', nargs='?', default='7777') return parser +def get_client_fullname(host, port): + return f'{ host }:{ port }' parser = createParser() args = parser.parse_args(sys.argv[1:]) @@ -33,45 +34,57 @@ def createParser(): sock.bind((args.addr, int(args.port))) sock.listen(5) -responses = [] +requests = [] connections = [] + + try: while True: # принимает сообщение клиента; + client, address = sock.accept() - connections.append(client) + client_full_name = get_client_fullname(*address) + connections.append((client_full_name, client)) - logger.info(f'Client detected {address}') + client_sockets = list(map(lambda item: item[1], connections)) - rlist, wlist, xlist = select.select(connections, connections, [], 0) + logger.info(f'Client detected {address}') - for client in connections: - if client in rlist: #соеденения на запись - data = client.recv(1024) - request = json.loads( - data.decode('utf-8') + rlist, wlist, xlist = select.select(client_sockets, client_sockets, [], 0) + + for client in wlist: + read_client_host, read_client_port = client.getsockname() + read_client_fullname = get_client_fullname( + read_client_host, + read_client_port + ) + data = client.recv(1024) + request = json.loads(data.decode('utf-8')) + requests.append((read_client_fullname, request)) + + print(requests) + + if requests: + request_client_fullname, request = requests.pop() + response = handle_client_request(request) + + print(request_client_fullname, request) + for client in rlist: + print('2' * 50) + write_client_host, write_client_port = client.getsockname() + write_client_fullname = get_client_fullname( + write_client_host, + write_client_port ) - action_name = request.get('action') - response = handle_client_request(request) - - if response.get('code') == 400: - logger.error(f'Bad Request: { action_name } request: { request }') - - if response.get('code') == 200: - responses.append(response) - response_string = json.dumps(response) - client.send(response_string.encode('utf-8')) - - if client in wlist: #соеденения слушатели - if responses: - for conn in wlist: - response_obj_string = json.dumps(responses) - conn.send(response_obj_string.encode('utf-8')) - if client in xlist: - pass - #client.close() - #logger.info(f"client {address} closed") + + if write_client_fullname != write_client_fullname: + response_string = json.dumps(response) + client.send(response_string.encode('utf-8')) + logger.info( + f'Response { response_string } sended to {client.getsockname()}' + ) + except KeyboardInterrupt: logger.info(f"server {address} closed") sock.close() From de4c24ab6cb02c9eb3f8c4dd530492d951ece9ae Mon Sep 17 00:00:00 2001 From: PAND-or Date: Tue, 26 Mar 2019 17:19:37 +0300 Subject: [PATCH 3/4] hw07 fix --- client/__main__.py | 32 ++++++++----- server/__main__.py | 117 +++++++++++++++++++++++++++------------------ server/protocol.py | 1 + 3 files changed, 92 insertions(+), 58 deletions(-) diff --git a/client/__main__.py b/client/__main__.py index e4017ad..7949d49 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -19,7 +19,7 @@ import re import sys import argparse -import socket +from socket import socket, AF_INET, SOCK_STREAM import json import hashlib from datetime import datetime @@ -42,7 +42,7 @@ def createParser(): port = int(re.search('[0-9]{2,}', args.port).group(0)) try: - sock = socket.socket() + sock = socket(AF_INET, SOCK_STREAM) sock.connect((args.host, port)) if args.mode == 'w': @@ -76,16 +76,26 @@ def createParser(): sock.send(msg_action.encode()) """ - + # получить ответ сервера; + data = sock.recv(1024) + response = json.loads( + data.decode('utf-8') + ) + # разобрать сообщение сервера; + + if response.get('response') == 200: + if response.get('alert'): + logger.debug(f"Response Message: {response.get('alert')}") + print( + f"Response Message: {response.get('alert')}" + ) + else: + logger.critical(f"Error request: {response.get('error')}") else: - while True: - rlist, wlist, xlist = select.select([], [sock], [], 0) - - response = sock.recv(1024) - - if response: - print(response.decode()) - break + while True: # Постоянный опрос сервера + tm = sock.recv(1024) + print("Текущее время: %s" % tm.decode('utf-8')) + s.close() except KeyboardInterrupt: logger.info(f"client closed") sock.close() diff --git a/server/__main__.py b/server/__main__.py index 868faa4..b885c85 100644 --- a/server/__main__.py +++ b/server/__main__.py @@ -3,7 +3,7 @@ import sys import json -import socket +from socket import socket, AF_INET, SOCK_STREAM import argparse import select @@ -26,65 +26,88 @@ def createParser(): def get_client_fullname(host, port): return f'{ host }:{ port }' + +def read_requests(r_clients, all_clients): + """ Чтение запросов из списка клиентов + """ + responses = {} # Словарь ответов сервера вида {сокет: запрос} + #print('read_requests') + for sock in r_clients: + try: + print('client 1') + data = sock.recv(1024).decode('utf-8') + responses[sock] = json.loads(data) + print(responses[sock]) + except: + print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) + all_clients.remove(sock) + + return responses + + +def write_responses(requests, w_clients, all_clients): + """ Эхо-ответ сервера клиентам, от которых были запросы + """ + + for sock in w_clients: + if sock in requests: + #print('write_responses') + response = handle_client_request(requests[sock]) + response_string = json.dumps(response) + + try: + # Подготовить и отправить ответ сервера + print('Сообщение отправлено') + sock.send(response_string.encode('utf-8')) + except: # Сокет недоступен, клиент отключился + print('Клиент {} {} отключилсяя'.format(sock.fileno(), sock.getpeername())) + #sock.close() + #all_clients.remove(sock) + + + parser = createParser() args = parser.parse_args(sys.argv[1:]) -sock = socket.socket() +sock = socket(AF_INET, SOCK_STREAM) sock.bind((args.addr, int(args.port))) sock.listen(5) +sock.settimeout(0.2) requests = [] connections = [] - +clients = [] try: while True: - # принимает сообщение клиента; - - client, address = sock.accept() - client_full_name = get_client_fullname(*address) - connections.append((client_full_name, client)) - - client_sockets = list(map(lambda item: item[1], connections)) - - logger.info(f'Client detected {address}') - - rlist, wlist, xlist = select.select(client_sockets, client_sockets, [], 0) - - for client in wlist: - read_client_host, read_client_port = client.getsockname() - read_client_fullname = get_client_fullname( - read_client_host, - read_client_port - ) - data = client.recv(1024) - request = json.loads(data.decode('utf-8')) - requests.append((read_client_fullname, request)) - - print(requests) - - if requests: - request_client_fullname, request = requests.pop() - response = handle_client_request(request) - - print(request_client_fullname, request) - for client in rlist: - print('2' * 50) - write_client_host, write_client_port = client.getsockname() - write_client_fullname = get_client_fullname( - write_client_host, - write_client_port - ) - - if write_client_fullname != write_client_fullname: - response_string = json.dumps(response) - client.send(response_string.encode('utf-8')) - logger.info( - f'Response { response_string } sended to {client.getsockname()}' - ) + try: + conn, addr = sock.accept() # Проверка подключений + except OSError as e: + pass # timeout вышел + else: + print("Получен запрос на соединение от %s" % str(addr)) + clients.append(conn) + finally: + # Проверить наличие событий ввода-вывода + wait = 0 + r = [] + w = [] + + + try: + r, w, e = select.select(clients, clients, [], wait) + + #print('r:', len(r), ' w:', len(w), ' e:', len(e)) + requests = read_requests(r, clients) # Сохраним запросы клиентов + if requests: + write_responses(requests, w, clients) # Выполним отправку ответов + except: + pass # Ничего не делать, если какой-то клиент отключился + + except KeyboardInterrupt: - logger.info(f"server {address} closed") + #logger.info(f"server {address} closed") sock.close() diff --git a/server/protocol.py b/server/protocol.py index 0a269fe..6886d51 100644 --- a/server/protocol.py +++ b/server/protocol.py @@ -2,6 +2,7 @@ def validate_request(raw): + #print(raw) request_time = raw.get('time') request_action = raw.get('action') if request_time and request_action: From a07bf7c0575ec65804227de29d3931430b329b7a Mon Sep 17 00:00:00 2001 From: PAND-or Date: Tue, 26 Mar 2019 17:54:26 +0300 Subject: [PATCH 4/4] hw07 fix --- client/__main__.py | 52 +++++++++++++++++++++------------- server/__main__.py | 35 +++++++++++------------ server/presence/controllers.py | 2 +- 3 files changed, 50 insertions(+), 39 deletions(-) diff --git a/client/__main__.py b/client/__main__.py index 7949d49..8845a51 100644 --- a/client/__main__.py +++ b/client/__main__.py @@ -27,7 +27,7 @@ import select -def createParser(): +def create_parser(): parser = argparse.ArgumentParser() parser.add_argument('host', nargs='?', default='localhost') parser.add_argument('port', nargs='?', default='7777') @@ -35,17 +35,41 @@ def createParser(): return parser +def read_response(response, mode='w'): + response = json.loads( + data.decode('utf-8') + ) + # разобрать сообщение сервера; -parser = createParser() + if response.get('response') == 200: + if response.get('alert'): + if mode == 'w': + logger.debug(f"Response Message: {response.get('alert')}") + print( + f"Response Message: {response.get('alert')}" + ) + else: + print( + f"{response.get('user')['account_name']}: {response.get('user')['status']}\n", + f"Server: {response.get('alert')}" + ) + else: + logger.critical(f"Error request: {response.get('error')}") + + +parser = create_parser() args = parser.parse_args(sys.argv[1:]) port = int(re.search('[0-9]{2,}', args.port).group(0)) + + try: sock = socket(AF_INET, SOCK_STREAM) sock.connect((args.host, port)) if args.mode == 'w': + username = input("Enter user Name: ") while True: # сформировать presence-сообщение; # В формате JIM @@ -59,8 +83,8 @@ def createParser(): "time": datetime.now().timestamp(), "type": "status", "user": { - "account_name": input("Enter user Name: "), - "status": input("Status message: ") + "account_name": username, + "status": input("Your message: ") } } ) @@ -78,24 +102,12 @@ def createParser(): """ # получить ответ сервера; data = sock.recv(1024) - response = json.loads( - data.decode('utf-8') - ) - # разобрать сообщение сервера; - - if response.get('response') == 200: - if response.get('alert'): - logger.debug(f"Response Message: {response.get('alert')}") - print( - f"Response Message: {response.get('alert')}" - ) - else: - logger.critical(f"Error request: {response.get('error')}") + read_response(data) else: while True: # Постоянный опрос сервера - tm = sock.recv(1024) - print("Текущее время: %s" % tm.decode('utf-8')) - s.close() + data = sock.recv(1024) + read_response(data, 'r') + #sock.close() except KeyboardInterrupt: logger.info(f"client closed") sock.close() diff --git a/server/__main__.py b/server/__main__.py index b885c85..705023f 100644 --- a/server/__main__.py +++ b/server/__main__.py @@ -30,40 +30,39 @@ def get_client_fullname(host, port): def read_requests(r_clients, all_clients): """ Чтение запросов из списка клиентов """ - responses = {} # Словарь ответов сервера вида {сокет: запрос} + responses = [] #print('read_requests') for sock in r_clients: try: print('client 1') data = sock.recv(1024).decode('utf-8') - responses[sock] = json.loads(data) + #responses[sock] = json.loads(data) + responses.append(json.loads(data)) print(responses[sock]) except: print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) - all_clients.remove(sock) + #all_clients.remove(sock) return responses def write_responses(requests, w_clients, all_clients): - """ Эхо-ответ сервера клиентам, от которых были запросы - """ - - for sock in w_clients: - if sock in requests: - #print('write_responses') - response = handle_client_request(requests[sock]) - response_string = json.dumps(response) - - try: - # Подготовить и отправить ответ сервера - print('Сообщение отправлено') + for req in requests: + #print('write_responses') + #print(req) + # Разобрать все запросы + response = handle_client_request(req) + response_string = json.dumps(response) + for sock in w_clients: + try: + # отправить всем sock.send(response_string.encode('utf-8')) - except: # Сокет недоступен, клиент отключился - print('Клиент {} {} отключилсяя'.format(sock.fileno(), sock.getpeername())) + #print('Сообщение отправлено') + except: # Сокет недоступен, клиент отключился + print('Клиент {} {} отключился'.format(sock.fileno(), sock.getpeername())) #sock.close() #all_clients.remove(sock) - + requests.remove(req) parser = createParser() diff --git a/server/presence/controllers.py b/server/presence/controllers.py index aff2945..c24cadf 100644 --- a/server/presence/controllers.py +++ b/server/presence/controllers.py @@ -9,5 +9,5 @@ def send_presence(request): return make_response( request, 200, - alert=f"Hi {user['account_name']}" + alert=f"{user['account_name']} Your message is send " )