В этой статье мы вернемся опять к теме обмена сообщениями через сервер. Такой простой вариант анонимного обмена сообщениями в терминале на популярном языке 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()