Обмен сообщения в терминале через общий сервер. Python

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

Сервер который хранит клиентов, сообщения и отправляет их. И клиентская часть подключается к серверу и отправляет и получает данные . Кроме самого Питона нам потребуется база данных SQL( например MariaDB).

Статьи которые могут пригодиться:

Настройка базы данных.

Тут мы создадим базу для проекта и нужные таблицы.

CREATE DATABASE testdb;
USE testdb;
CREATE TABLE user_tbl(id VARCHAR(20) NOT NULL , pass VARCHAR(40) NOT NULL);
CREATE TABLE message_tbl(id INT NOT NULL AUTO_INCREMENT, user VARCHAR(20) NOT NULL, data VARCHAR(1400) NOT NULL, sender VARCHAR(20) NOT NULL, PRIMARY KEY ( id ));

Код Сервера.

Нам потребуется только одна библиотека для работы с базой данных pip install PyMySQL. Ну и примитивный API для общения сервером. То есть клиент будет отсылать определенные команды и данные в определенном порядке.

  • #reg — Клиент отправляет команду и хэш пароля. Сервер возвращает присвоенный ID клиента.
  • #get — Клиент отправляет запрос на получение данных, свой ID и хэш пароля для валидации. Сервер отправляет ему его сообщения которые накопились.
  • #send_to — Клиент отправляет ID получателя сообщения, сам текс и свой ID. Сервер сохраняет сообщения.
import socket
import pymysql
import random

def indifiti(data):
    print('Indifini ID -', data[1])
    # data = #get, id, pass
    cursor = conn.cursor()
    #user_tbl(id VARCHAR(20) , pass VARCHAR(40));
    cursor.execute("SELECT pass FROM user_tbl WHERE id = '" + str(data[1]) + "';")
    result = cursor.fetchall()
    conn.commit()
    cursor.close()
    if str(result[0][0]) == data[2]:
        return True
    else:
        return False


def get(data,addres):
    # data = #get, id, pass
    if indifiti(data) == True:
        cursor = conn.cursor()
        #SELECT * FROM message_tbl WHERE user = '';
        cursor.execute("SELECT * FROM message_tbl WHERE user = '" + str(data[1]) + "';")
        #message_tbl(id , user VARCHAR(20) , data VARCHAR(1400) , sender VARCHAR(20)
        result = cursor.fetchall()
        for i in result:
            if i[1] == data[1]:
                message = '\033[36m{}\033[0m'.format('[' + i[3] + ']') + '\033[33m{}\033[0m'.format(i[2])
                sock.sendto(message.encode('utf-8'), addres)
                #DELETE FROM message_tbl WHERE id = 1;
                #print("DELETE FROM message_tbl WHERE id = " + i[0] + ";")
                cursor.execute("DELETE FROM message_tbl WHERE id = " + str(i[0]) + ";")
        conn.commit()
        cursor.close()
        sock.sendto('#null'.encode('utf-8'), addres)
    else:
        sock.sendto('Not Indifiti'.encode('utf-8'), addres)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('127.0.0.1', 5000))
print('Start Server')

conn = pymysql.connect(host='localhost',
        user='root',
        password='1234',
        db='testdb')


while True:
    data, addres = sock.recvfrom(1024)
    data = data.decode('utf-8').split(',,')
    if data[0] == '#reg': # data(#reg , pass)
        cursor = conn.cursor()
        tmp = (random.randint(0, 5000000) + random.randint(0, 5000000)) // 2
        select = "INSERT INTO user_tbl (id, pass) VALUES ('" + str(tmp) + "'" + ", '" + str(data[1]) + "'" + ");"
        cursor.execute(select)
        conn.commit()
        cursor.close()
        sock.sendto(str(tmp).encode('utf-8'), addres)
    elif data[0] == '#get':
        get(data, addres)
    elif data[0] == '#send_to':
        print('For -', data[1], 'Text--', data[2])
        #data = #send_to, ID, text, sender
        cursor = conn.cursor()
        # INSERT INTO test_tbl (user, data,sender) VALUES ();
        cursor.execute(
            "INSERT INTO message_tbl (user, data, sender) VALUES ('" + str(data[1]) + "','" + str(data[2]) + "','" + str(data[3]) + "');")
        conn.commit()
        cursor.close()

Код Клиента.

import socket
import threading
import hashlib
import os
import time

SERVER = '127.0.0.1', 5000

def reg():
    password = input('Enter Password: ')
    hash_pass = hashlib.md5(password.encode())
    hash_pass = hash_pass.hexdigest()
    message = '#reg' + ',,' + hash_pass
    sock.sendto(message.encode('utf-8'), SERVER)
    data, addres = sock.recvfrom(1024)
    return data.decode('utf-8'), hash_pass

def start():
    if os.path.exists('id.log') != True:
        id, hash_pass = reg()
        file = open('id.log', 'w')
        file.write(str(id))
        file.close()
        # '\033[31m{}\033[0m'.format() Red Text
        print('You ID# ' + '\033[31m{}\033[0m'.format(id))
        return id, hash_pass
    file = open('id.log', 'r')
    id = file.read()
    file.close()
    print('You ID# ' + '\033[31m{}\033[0m'.format(id))
    while True:
        password = input('Enter Password: ')
        hash_pass = hashlib.md5(password.encode())
        hash_pass = hash_pass.hexdigest()
        message = '#get' + ',,' + id + ',,' + hash_pass
        sock.sendto(message.encode('utf-8'), SERVER)
        while True:
            data, addres = sock.recvfrom(1024)
            if data.decode('utf-8') == '#null':
                return id, hash_pass
            elif data.decode('utf-8') == 'Not Indifiti':
                print(data.decode('utf-8'))
                break
            print(data.decode('utf-8'))

def get():
    while True:
        message = '#get' + ',,' + TITLE
        # message = #get,id,pass
        sock.sendto(message.encode('utf-8'), SERVER)
        while True:
            data, addres = sock.recvfrom(1024)
            if data.decode('utf-8') != '#null':
                print(data.decode('utf-8'))
            else:
                break
        time.sleep(30)

def send_to():
    while True:
        id_user = input('Enter ID_USER: ')
        text = input('Enter text: ')
        message = '#send_to' + ',,' + id_user + ',,' + text + ',,' + ID
        sock.sendto(message.encode('utf-8'), SERVER)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('127.0.0.1', 0))
ID, PASS = start()
TITLE = ID + ',,' + PASS
potok_teg = threading.Thread(target=get)
potok_send = threading.Thread(target=send_to)
potok_teg.start()
potok_send.start()

Ошибка в тексте? Выделите её и нажмите «Ctrl + Enter»

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *