Advertisement
pegorino

server

Jan 11th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.91 KB | None | 0 0
  1. import select
  2.  
  3. from socket import socket, AF_INET, SOCK_STREAM
  4. from usefull_utils import parse
  5.  
  6. from log_config import server_log
  7.  
  8. HOST = ''
  9. PORT = 7777
  10.  
  11. SIZE = 1024
  12.  
  13. CODES = {100: 'Базовое уведомление', 101: 'Важное уведомление', 200: 'ОК', 201: 'Объект создан',
  14.          202: 'Подтверждение', 400: 'Неправильный запрос/JSON-объект', 401: 'Не авторизован',
  15.          402: 'Неправильный логин/пароль', 403: 'Пользователь заблокирован',
  16.          404: 'Пользователь/чат отсутствует на сервере', 409: 'Уже имеется подключение с указанным логином',
  17.          410: 'Адресат существует, но недоступен(offline)', 500: 'Ошибка сервера'}
  18.  
  19. CODE = 200
  20.  
  21. # @server_log
  22. def read_requests(r_clients, all_clients, size=SIZE):
  23.     ''' Чтение запросов из списка клиентов
  24.    '''
  25.     responses = {}  # Словарь ответов сервера вида {сокет: запрос}
  26.  
  27.     for sock in r_clients:
  28.         try:
  29.  
  30.             bdata = sock.recv(size)
  31.             data = parse(bdata)
  32.             responses[sock] = data
  33.             print('\nr --> ', [(c.fileno(), c.getpeername()[1]) for c in r_clients])
  34.             print('Client {} writes in {}'.format(data['from'], data['to']), end=': ')
  35.  
  36.         except:
  37.             print('Client (r) {} {} disconnected'.format(sock.fileno(), sock.getpeername()))
  38.             all_clients.remove(sock)
  39.             # print('all (r)--> ', [(c.fileno(), c.getpeername()[1]) for c in all_clients])
  40.  
  41.     return responses
  42.  
  43. # @server_log
  44. def write_responses(requests, w_clients, all_clients):
  45.     ''' Эхо-ответ сервера клиентам, от которых были запросы
  46.    '''
  47.     for sock in w_clients:
  48.         if sock in requests:
  49.             # w_clients.remove(sock)  # не отправлять сообщение самому себе. в реальном чате убрать эту строку?
  50.             try:
  51.  
  52.                 # Подготовить и отправить ответ сервера
  53.                 try:
  54.                     message = {'message from': requests[sock]['from'], 'text': requests[sock]['message'],
  55.                            'time': requests[sock]['time']}
  56.                     print(message)
  57.                     bmessage = parse(message)
  58.  
  59.                 except TypeError:
  60.                     pass
  61.                     # print('Writer disconnected. Nothing to receive.')
  62.  
  63.                 else:
  64.  
  65.                     for w_client in w_clients:
  66.                         if w_client not in requests:
  67.                             w_client.send(bmessage)
  68.                             print('(server) send message to {}'.format(w_client.getpeername()[1]), bmessage)
  69.  
  70.                     print('w --> ', [(c.fileno(), c.getpeername()[1]) for c in w_clients])
  71.                     print('requests --> ', requests)
  72.  
  73.             # ???сюда не заходит???
  74.             except:  # Сокет недоступен, клиент отключился
  75.                 print('Client (w) {} {} disconnected'.format(sock.fileno(), sock.getpeername()))
  76.                 sock.close()
  77.                 all_clients.remove(sock)
  78.                 # print('all (w)--> ', [(c.fileno(), c.getpeername()[1]) for c in all_clients])
  79.  
  80.  
  81. def mainloop():
  82.     ''' Основной цикл обработки запросов клиентов
  83.    '''
  84.  
  85.     #TODO реализовать запуск сервера из коммандной строки
  86.     #TODO в cmd_utils уже есть cmd_server!
  87.  
  88.     address = (HOST, PORT)
  89.     clients = []
  90.  
  91.     s = socket(AF_INET, SOCK_STREAM)
  92.     s.bind(address)
  93.     s.listen(5)
  94.     s.settimeout(0.2)  # Таймаут для операций с сокетом
  95.     while True:
  96.         try:
  97.             conn, addr = s.accept()  # Проверка подключений
  98.         except OSError as e:
  99.             pass  # timeout вышел
  100.         else:
  101.             print('request to connect from {}'.format(addr[1]))
  102.             clients.append(conn)
  103.         finally:
  104.             # Проверить наличие событий ввода-вывода
  105.             wait = 0
  106.             r = []
  107.             w = []
  108.             try:
  109.                 r, w, e = select.select(clients, clients, [], wait)
  110.  
  111.             except:
  112.                 pass  # Ничего не делать, если какой-то клиент отключился
  113.  
  114.             requests = read_requests(r, clients)  # Сохраним запросы клиентов
  115.  
  116.             write_responses(requests, w, clients)  # Выполним отправку ответов клиентам
  117.  
  118.  
  119. if __name__ == '__main__':
  120.     print('Server runs!\n')
  121.     mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement