I ask for your advice. I want to implement a simple chat on python c one condition – registration “chatters”.
(Participant Nick chat can be reserved for themselves, and entering a password – log in with your nickname IM)
The very logic of a conventional client-server chat and I realized there were no problems as long as there was the process of “registration” in the chat.
The logic of:
- The connection to the server
- Introduction of the name
- The statement that the name was entered correctly
- The introduction of a password
- Re-introduction of the password
- The user enters a general chat
Describe the problem in words:
It is impossible to realize the method / principle / logic, in which the server is listening to user upon registration only sockets from the user. Simply put, all sockets from other members knock all logic. It turns out: there is user registration №1 (any stage), the user comes and knocks №2 registered user №1. I can not figure out how to create a “session” with a specific user. Please help. Code quote below:
The client code:
import socket
import threading
SERVER_ADDRESS = ( 'localhost', 8125)
sor = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
sor.bind (( '', 0))
sor.sendto (( 'Connect to server'). encode ( 'utf-8'), SERVER_ADDRESS)
def reading_socket ():
While True:
data = sor.recv (1024)
print (data.decode ( 'utf-8'))
potok = threading.Thread (target = reading_socket)
potok.start ()
While True:
message = input ()
sor.sendto ((message) .encode ( 'utf-8'), SERVER_ADDRESS)
Server ID:
import socket
SERVER_ADDRESS = ( 'localhost', 8125)
server_socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind (SERVER_ADDRESS)
clients = []
members = {}
print ( "Server is running")
# HERE More functions "Register"
# With the username and confirmation PASSWORD
def register_on_chat (port_address):
register_data = 'You must be registered, please enter your nickname:'
server_socket.sendto (register_data.encode ( 'utf-8'), address)
def confirm_nickname (port_address):
name, address = server_socket.recvfrom (1024)
registration_data = f "Your nickname {name.decode ( 'utf-8')} Enter Ues or No."
server_socket.sendto (registration_data.encode ( 'utf-8'), address)
append_to_list (name, port_address)
def new_nickmane (address):
registration_data = 'Enter your username'
server_socket.sendto (registration_data.encode ( 'utf-8'), address)
confirm_nickname (address)
def append_to_list (name, port_address):
data, address = server_socket.recvfrom (1024)
if data.decode ( 'utf-8') == 'Yes':
get_pass (name)
elif data.decode ( 'utf-8') == 'No':
new_nickmane (port_address)
def get_pass (name):
pass_data_1 = f "Hello {name.decode ( 'utf-8')} Enter the password for your nickname:"
server_socket.sendto (pass_data_1.encode ( 'utf-8'), address)
password_1, adr = server_socket.recvfrom (1024)
pass_data_2 = "Confirm password"
server_socket.sendto (pass_data_2.encode ( 'utf-8'), address)
password_2, adr = server_socket.recvfrom (1024)
if password_1 == password_2:
members [name.decode ( 'utf-8')] = password_1.decode ( 'utf-8')
pass_data_3 = "Excellent, registration was successful"
server_socket.sendto (pass_data_3.encode ( 'utf-8'), address)
PRINT (Members)
ELSE:
pass_data_4 = "Let's try again"
server_socket.sendto (pass_data_4.encode ( 'utf-8'), address)
get_pass (name)
confirm_nickname (port_address)
While True:
data, address = server_socket.recvfrom (1024)
print (address [0], address [1])
if address not in clients:
clients.append (address)
register_on_chat (address)
text = "Registration successful. Welcome to the chat!"
server_socket.sendto (text.encode ( 'utf-8'), address)
For client in clients:
If Client == Address:
text_from_client = Data.Decode ('UTF-8')
Print (Text_From_Client)
Continue.
Server_Socket.Sendto (Data, Client)
Thank you for the advice.
Answer 1, Authority 100%
You need to create sessions for users and separate them from receiving data.
class session:
Def __init __ (Self, Address, Sock):
self.state = 'init'
self.address = address
DEF ON_MESSAGE (Self, Message):
if self.state == 'init':
Answer = 'You must register, enter your nickname:'
Elif Self.state == 'WaitName':
Answer = F'wash Nick {Message} '
Self.nick = Message.
.......
Return Answer.
....
clients = {}
While True:
Data, Address = Server_socket.RecvFrom (1024)
session = clients.get (Address, None)
if not session:
Session = Session (Address, Server_Socket)
clients [address] = session
answer = session.on_message (data.decode ('UTF-8'))
Self.Sock.sendto (Answer.encode ('UTF-8'), Address)
If session.state == 'Chat':
For other_session in clients.values ():
If other_session.state == 'Chat':
self.sock.sendto (f "{session.nick}: {Data} \ n" .encode ('UTF-8'), Other_Session.Address)
SESSION class will store chat status and set the following question depending on this state. And the dictionary Clients will be a binding session to a specific client, and not just a list of addresses.
is possible without a class, and the state is stored in the dictionary.