Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import select
- from socket import socket, AF_INET, SOCK_STREAM
- from usefull_utils import parse
- from log_config import server_log
- HOST = ''
- PORT = 7777
- SIZE = 1024
- CODES = {100: 'Базовое уведомление', 101: 'Важное уведомление', 200: 'ОК', 201: 'Объект создан',
- 202: 'Подтверждение', 400: 'Неправильный запрос/JSON-объект', 401: 'Не авторизован',
- 402: 'Неправильный логин/пароль', 403: 'Пользователь заблокирован',
- 404: 'Пользователь/чат отсутствует на сервере', 409: 'Уже имеется подключение с указанным логином',
- 410: 'Адресат существует, но недоступен(offline)', 500: 'Ошибка сервера'}
- CODE = 200
- # @server_log
- def read_requests(r_clients, all_clients, size=SIZE):
- ''' Чтение запросов из списка клиентов
- '''
- responses = {} # Словарь ответов сервера вида {сокет: запрос}
- for sock in r_clients:
- try:
- bdata = sock.recv(size)
- data = parse(bdata)
- responses[sock] = data
- print('\nr --> ', [(c.fileno(), c.getpeername()[1]) for c in r_clients])
- print('Client {} writes in {}'.format(data['from'], data['to']), end=': ')
- except:
- print('Client (r) {} {} disconnected'.format(sock.fileno(), sock.getpeername()))
- all_clients.remove(sock)
- # print('all (r)--> ', [(c.fileno(), c.getpeername()[1]) for c in all_clients])
- return responses
- # @server_log
- def write_responses(requests, w_clients, all_clients):
- ''' Эхо-ответ сервера клиентам, от которых были запросы
- '''
- for sock in w_clients:
- if sock in requests:
- # w_clients.remove(sock) # не отправлять сообщение самому себе. в реальном чате убрать эту строку?
- try:
- # Подготовить и отправить ответ сервера
- try:
- message = {'message from': requests[sock]['from'], 'text': requests[sock]['message'],
- 'time': requests[sock]['time']}
- print(message)
- bmessage = parse(message)
- except TypeError:
- pass
- # print('Writer disconnected. Nothing to receive.')
- else:
- for w_client in w_clients:
- if w_client not in requests:
- w_client.send(bmessage)
- print('(server) send message to {}'.format(w_client.getpeername()[1]), bmessage)
- print('w --> ', [(c.fileno(), c.getpeername()[1]) for c in w_clients])
- print('requests --> ', requests)
- # ???сюда не заходит???
- except: # Сокет недоступен, клиент отключился
- print('Client (w) {} {} disconnected'.format(sock.fileno(), sock.getpeername()))
- sock.close()
- all_clients.remove(sock)
- # print('all (w)--> ', [(c.fileno(), c.getpeername()[1]) for c in all_clients])
- def mainloop():
- ''' Основной цикл обработки запросов клиентов
- '''
- #TODO реализовать запуск сервера из коммандной строки
- #TODO в cmd_utils уже есть cmd_server!
- address = (HOST, PORT)
- clients = []
- s = socket(AF_INET, SOCK_STREAM)
- s.bind(address)
- s.listen(5)
- s.settimeout(0.2) # Таймаут для операций с сокетом
- while True:
- try:
- conn, addr = s.accept() # Проверка подключений
- except OSError as e:
- pass # timeout вышел
- else:
- print('request to connect from {}'.format(addr[1]))
- clients.append(conn)
- finally:
- # Проверить наличие событий ввода-вывода
- wait = 0
- r = []
- w = []
- try:
- r, w, e = select.select(clients, clients, [], wait)
- except:
- pass # Ничего не делать, если какой-то клиент отключился
- requests = read_requests(r, clients) # Сохраним запросы клиентов
- write_responses(requests, w, clients) # Выполним отправку ответов клиентам
- if __name__ == '__main__':
- print('Server runs!\n')
- mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement