Розробка примітивного месенджера на Python за допомогою бібліотеки socket

БІЛЬШ ДЕТАЛЬНЕ ПОЯСНЕННЯВ КІНЦІ

Вступ

У сучасному світі зв'язок через Інтернет став невід'ємною частиною нашого повсякденного життя. Одним з найпопулярніших способів спілкування є месенджери, які дозволяють надсилати повідомлення в режимі реального часу. Ви могли помітити, що багато месенджерів мають складну архітектуру та велику кількість функціональності, але ми хочемо показати вам, як легко розробити свій власний примітивний месенджер за допомогою мови програмування Python та бібліотеки сокет.

Python є потужною та простою у використанні мовою програмування, яка надає нам багато можливостей для розробки мережевих додатків. Одним з найважливіших компонентів розробки мережевих додатків є робота з сокетами. Сокети - це механізм, який дозволяє взаємодіяти з мережею та передавати дані між різними комп'ютерами. Вони є основою багатьох мережевих протоколів, включаючи HTTP, FTP та інші.

У цій статті ми покажемо вам, як використовувати бібліотеку сокет у Python для створення примітивного месенджера. Ми розглянемо як клієнтську, так і серверну частину коду та покажемо, як вони взаємодіють між собою для обміну повідомленнями у режимі реального часу.


Любий читачу, якщо тобі подобається подібні довгочити та ти хотів би побачити еволюцію цього проекту в майбутньому, то вподобай цю публікацію!

Також переглянь працю, на якої базувався цей код:

Також цікаві праці пов'язані з програмуванням:


Пишемо сервер

Почнемо з бази. Ви маєте визначити ваш IPv4. Для цього в cmd треба написати:

ipconfig

Після чого вам буде надано все необхідне, а саме IP.

Починаємо писати

import socket
import threading

Ми імпортуємо бібліотеку сокет для реалізації сервера, а потім срід для опрацювання клієнтів.

HOST = "IPv4"#Сюди писати те, що отримано з ipconfig
PORT = 1026 #Порт може бути від 1022 і далі

Тепер створюємо змінні зі значеням апі та порту. І ось зара буде найвеселіша частина.

# Створення сокету
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()

# Список для збереження підключених клієнтів
clients = []

Ми створюємо сокет та передаємо наші змінні до нього. А тепер я покажу загальний код, знизу буде розписано всі функції.

import socket
import threading
HOST = "IPv4"#Сюди писати те, що отримано з ipconfig
PORT = 1026 #Порт може бути від 1022 і далі
# Створення сокету
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()

# Список для збереження підключених клієнтів
clients = []
# Функція, що обробляє підключення клієнтів
def handle_client(client_socket, client_address):
    while True:
        # Отримання повідомлення від клієнта
        message = client_socket.recv(PORT)
        if not message:
            # Якщо повідомлення порожнє, то клієнт відключився
            clients.remove(client_socket)
            print(f"Відключено від {client_address}")
            client_socket.close()
            break
        # Виведення отриманого повідомлення на екран
        print(f"Отримано {message.decode()} від {client_address}")
        # Відправлення повідомлення всім підключеним клієнтам, крім відправника
        for client in clients:
            if client != client_socket:
                client.sendall(message)

# Функція, що очікує підключення нових клієнтів
def accept_clients():
    while True:
        client_socket, client_address = server_socket.accept()
        clients.append(client_socket)
        # Запуск нового потоку для обробки підключення клієнта
        client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
        client_thread.start()

accept_clients()

Цей код створює TCP-сервер, який прослуховує підключення клієнтів за вказаною IP-адресою (HOST) та номером порту (PORT). Він зберігає список підключених клієнтів і обробляє кожне підключення клієнта у окремому потоці.

Функція handle_client

відповідає за обробку підключень клієнтів. Вона отримує повідомлення від клієнта та відправляє його всім іншим підключеним клієнтам. Якщо клієнт відключається, його видаляють зі списку та закривають сокет.

Функція accept_clients

безперервно очікує нові підключення клієнтів. Для кожного нового підключення вона додає клієнта до списку і запускає новий потік для обробки комунікації з клієнтом.

У цілому, цей код дозволяє декільком клієнтам підключатися до сервера та обмінюватися повідомленнями між собою.

Клієнтська частина

import socket
import threading

HOST = "IPv4"#Сюди писати те, що отримано з ipconfig
PORT = 1026 #Порт може бути від 1022 і далі

# Створюємо сокет і встановлюємо з'єднання з сервером
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect((HOST, PORT))

    # Функція для отримання повідомлень від сервера
    def receive_messages():
        while True:
            received = str(sock.recv(PORT), "utf-8")  # Отримуємо повідомлення від сервера
            print("\nServer message: {}".format(received))  # Виводимо отримане повідомлення на екран

    receive_thread = threading.Thread(target=receive_messages)  # Створюємо окремий потік для отримання повідомлень
    receive_thread.start()  # Запускаємо потік

    while True:
        message = input("Type your message: ")  # Користувач вводить повідомлення з консолі
        sock.sendall(bytes(message + "\n", "utf-8"))  # Відправляємо повідомлення на сервер

Клієнтська частина коду є частиною програми, яка взаємодіє з сервером за допомогою сокетів. Вона дозволяє користувачеві надсилати повідомлення на сервер і отримувати повідомлення від нього.

Основні кроки в роботі клієнта:

  1. Встановлення з'єднання: Клієнт створює сокет і встановлює з'єднання з сервером, використовуючи IP-адресу та порт сервера.

  2. Отримання повідомлень від сервера: Клієнт створює окремий потік для отримання повідомлень від сервера. У цьому потоці він безкінечно чекає на отримання повідомлень від сервера. Коли отримує повідомлення, воно виводиться на екран.

  3. Відправлення повідомлень на сервер: Клієнт чекає на введення повідомлення користувачем з консолі. Після введення клієнт відправляє це повідомлення на сервер.

  4. Закриття з'єднання: Клієнт може закрити з'єднання з сервером, коли більше не потрібно взаємодіяти. У даному коді це відбувається автоматично при виході з блоку with, але в інших випадках може знадобитися явне закриття сокету.

За бажанням, ви можете додати туди графічного інтерфейсу та буде ще краще. Але моя ціль була попрацювати з мережами в пітоні. До того ж, цей месенжер не буде мати шифрування. Тож не раджу таким користуватися не в рамках навчання.

Детальне пояснення серверної частини

  1. handle_client(client_socket, client_address): Ця функція обробляє комунікацію з підключеним клієнтом. Вона приймає два аргументи - client_socket (сокет клієнта) та client_address (адреса клієнта). У циклі while True, функція очікує отримання повідомлення від клієнта за допомогою client_socket.recv(PORT). Якщо повідомлення не має даних (порожнє), це означає, що клієнт відключився. Тоді функція видаляє client_socket зі списку clients, закриває сокет client_socket та виходить з циклу while. Якщо повідомлення не порожнє, функція виводить його на екран разом із адресою клієнта. Потім вона перебирає всіх підключених клієнтів у списку clients і відправляє отримане повідомлення (message) усім клієнтам, окрім відправника.

  2. accept_clients(): Ця функція відповідає за прийом нових підключень клієнтів. Вона безперервно виконується у циклі while True. У циклі викликається метод server_socket.accept(), який блокує виконання програми і очікує підключення нового клієнта. Коли новий клієнт підключається, server_socket.accept() повертає кортеж з двома значеннями - client_socket (сокет клієнта) і client_address (адреса клієнта). Функція додає client_socket до списку clients і створює новий потік (client_thread) для обробки комунікації з клієнтом, передаючи client_socket і client_address як аргументи у функцію handle_client. Після створення потоку, він запускається за допомогою методу start().

  3. Основна частина програми: На початку програми задаються значення для HOST (IP-адреса) і PORT (номер порту). Далі створюється сокет сервера (server_socket), встановлюється його адреса та починається прослуховування підключень за допомогою методу listen().

  4. Ініціалізується пустий список clients, в якому будуть зберігатися підключені клієнти.

  5. Запускається функція accept_clients() в окремому потоці. Ця функція буде безперервно приймати нові підключення клієнтів.

Основна ідея програми полягає в тому, що вона створює сервер, який приймає підключення від багатьох клієнтів і передає повідомлення від одного клієнта до всіх інших. Кожне підключення обробляється у своєму потоці, що дозволяє одночасно працювати з декількома клієнтами

Детальне пояснення клієнтської частини

Цей код створює клієнтську програму, яка підключається до сервера за допомогою сокетів.

  1. Визначаються значення HOST (ім'я хосту або IP-адреса сервера) і PORT (порт, що використовується сервером).

  2. Створюється сокет (sock) за допомогою socket.socket(), використовуючи AF_INET для IPv4 і SOCK_STREAM для TCP з'єднання.

  3. З'єднання з сервером встановлюється за допомогою sock.connect((HOST, PORT)).

  4. Функція receive_messages використовується для прийому повідомлень від сервера. Вона безкінечно виконується у циклі while True. Повідомлення отримується з використанням sock.recv(PORT) та перетворюється у рядок з кодуванням UTF-8. Отримане повідомлення виводиться на екран.

  5. Створюється окремий потік (receive_thread) для виконання функції receive_messages. Це дозволяє одночасно приймати повідомлення від сервера та відправляти повідомлення на сервер.

  6. У циклі while True користувач може вводити повідомлення з консолі за допомогою input(). Введене повідомлення відправляється на сервер за допомогою sock.sendall(). Повідомлення перетворюється у байтовий рядок з кодуванням UTF-8 перед відправкою.

Цей код дозволяє клієнту взаємодіяти з сервером, надсилаючи та отримуючи повідомлення.

Розширюйте, покращуйте, вдосконалюйте, зміцнюйте український контент.

Слава Україні!

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Пан Євген
Пан Євген@Ukrainian

3.6KПрочитань
0Автори
65Читачі
На Друкарні з 16 квітня

Більше від автора

Вам також сподобається

  • Чи може штучний інтелект замінити живих перекладачів?

    Штучний інтелект (ШІ) зробив значний прогрес у галузі перекладу в останні роки. Деякі програми ШІ тепер здатні надавати переклади, які не відрізняються від перекладів, зроблених людьми. Це призвело до появи припущення, що ШІ може врешті-решт замінити живих перекладачів.

    Теми цього довгочиту:

    Штучний Інтелект
  • Звідки взявся антисемітизм

    Серед всіх антисемітів мене дивувало, що ніхто з них не може пояснити, чому вони антисеміти. Український антисемітизм існує, він не міг не з'явитися і на це існує багато причин. Сьогодні про це і поговоримо.

    Теми цього довгочиту:

    Євреї
  • Чому Discord перейшов з Go на Rust

    Rust стає першокласною мовою в різних областях. Ми в Discord успішно використовуємо його і на серверній, і на стороні клієнта.

    Теми цього довгочиту:

    Discord

Коментарі (8)

Шо думаєте?

Вам також сподобається

  • Чи може штучний інтелект замінити живих перекладачів?

    Штучний інтелект (ШІ) зробив значний прогрес у галузі перекладу в останні роки. Деякі програми ШІ тепер здатні надавати переклади, які не відрізняються від перекладів, зроблених людьми. Це призвело до появи припущення, що ШІ може врешті-решт замінити живих перекладачів.

    Теми цього довгочиту:

    Штучний Інтелект
  • Звідки взявся антисемітизм

    Серед всіх антисемітів мене дивувало, що ніхто з них не може пояснити, чому вони антисеміти. Український антисемітизм існує, він не міг не з'явитися і на це існує багато причин. Сьогодні про це і поговоримо.

    Теми цього довгочиту:

    Євреї
  • Чому Discord перейшов з Go на Rust

    Rust стає першокласною мовою в різних областях. Ми в Discord успішно використовуємо його і на серверній, і на стороні клієнта.

    Теми цього довгочиту:

    Discord