ζ༼Ɵ͆ل͜Ɵ͆༽ᶘ

Простой Python чат (клиент/сервер)

2 комментов
07.08.2020
3 мин чтения

Python - один из самых универсальных языков программирования, и это можно наблюдать через его различные приложения повсюду. Вот пример того, как вы можете построить простой чат сервер на основе командной строки с помощью python, который легко реализовать и понять. Так что давайте начнем.


Что такое чат-комната?

Чат-комната - это среда / интерфейс, который позволяет двум или более людям общаться и отправлять сообщения всем желающим. Это может быть как межличностный (один на один), так и групповой чат. Сейчас мы создадим комнату группового чата, в которой одновременно могут находиться более двух клиентов.


Устройство

Для чата мы будем использовать серверно-клиентскую архитектуру или чат клиент сервер. Это означает, что несколько клиентов будут размещены на одном сервере.

Приступая к работе

Прежде чем погрузиться в код, последнее, что мы хотим знать, это следовать этой архитектуре, нам нужно написать два сценария, один для серверной стороны, а другой для клиентской. Одна вещь, которая должна быть очень ясной, заключается в том, что клиенты будут общаться только через сервер. Между ними не будет прямой связи. Итак, давайте погрузимся в код.

Сервер Сначала импортируем две библиотеки – socket и threading. Socket даст возможность коммуникации, а threading позволит работать с несколькими процессами одновременно. Дальше нужно определить ip и порт. Порт не должен быть занят каким-либо процессом. Сокет использует два параметра: AF_INET (использование сокета) и SOCK_STREAM (использование TCP-протокола).

Дальше понадобится функция связи. Она будет ретранслировать сообщения каждого клиента для всех остальных. Функция, которая подключает пользователей, запрашивает имя пользователя при помощи ключевого слова ‘NICKNAME’. Если возникнут проблемы с каким-то клиентом, то он будет удалён. Чтобы подключиться к такому серверу, достаточно знать его ip и адрес порта:

# server.py
import socket, threading  # Импорт библиотек

host = '127.0.0.1'  # Локальный хост компьютера
port = 7976  # Выбор незарезервированного порта

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Инициализация сокета
server.bind((host, port))  # Назначение хоста и порта к сокету
server.listen()

clients = []
nicknames = []


def broadcast(message):  # Функция связи
    for client in clients:
        client.send(message)


def handle(client):
    while True:
        try:  # Получение сообщений от клиента
            message = client.recv(1024)
            broadcast(message)
        except:  # Удаление клиентов
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            broadcast('{} ушел!'.format(nickname).encode('utf-8'))
            nicknames.remove(nickname)
            break


def receive():  # Подключение нескольких клиентов
    while True:
        client, address = server.accept()
        print("Соединён с {}".format(str(address)))
        client.send('NICKNAME'.encode('utf-8'))
        nickname = client.recv(1024).decode('utf-8')
        nicknames.append(nickname)
        clients.append(client)
        print("Имя пользователя {}".format(nickname))
        broadcast("{} присоединился!".format(nickname).encode('utf-8'))
        client.send('Подключён к серверу!'.encode('utf-8'))
        thread = threading.Thread(target=handle, args=(client,))
        thread.start()


receive()

Клиент

В коде клиента нам опять понадобятся socket и threading. После инициализации сокета подключим его к ip и порту. Для правильной работы они должны быть такими же, как у сервера. После подключения к серверу можно начать отправку сообщений. Для этого нужна отдельная функция. И ей как раз понадобятся потоки. Сообщения при отправке кодируются в UTF-8.

 # client.py

import socket, threading

nickname = input("Выберите имя пользователя: ")

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Инициализация сокета

client.connect(('127.0.0.1', 7976))  # Соединение клиента с сервером

def receive():
    while True:  # Подтверждение соединения
        try:
            message = client.recv(1024).decode('utf-8')
            if message == 'NICKNAME':
                client.send(nickname.encode('utf-8'))
            else:
                print(message)

        except:  # Если неправильный ip или порт
            print("Ошибка!")
            client.close()
            break

def write():
    while True:  # Вывод сообщений в чат
        message = '{}: {}'.format(nickname, input(''))
        client.send(message.encode('utf-8'))

receive_thread = threading.Thread(target=receive)  # Получение всех сообщений
receive_thread.start()
write_thread = threading.Thread(target=write)  # Отправка всех сообщений
write_thread.start()

Тестирование

Помните, что сначала будет запущен сервер, а затем к нему могут присоединиться несколько клиентов. Это может быть выполнено в командной строке, но нам нужны разные терминалы, чтобы выполнить их по отдельности.

Ну вот и все для этого кода, надеюсь, он вам понравился!

11
Сегодня
День улёта