I've been following a tutorial on how to make multi-client chat using socket with python 3. So far I've got it working.
(我一直在遵循有关如何使用python 3使用套接字进行多客户端聊天的教程。到目前为止,我已经开始使用它了。)
Here's my code: (这是我的代码:)
server.py
(server.py)
import socket
import select
Header_Length = 10
IP = "127.0.0.1"
PORT = 1234
class Channels(object):
name = ""
members = ""
# Class constructor
def __init__(self, name):
self.name = name
self.members = set()
def AddUserToChannel(self, client):
if client not in members:
self.members.add(client)
else:
print('Member already exists in this channel.')
def RemoveUserFromChannel(self, client):
self.members.discard(client)
def make_channel():
channel = Channel(name, members)
return channel
# Creating socket with IPv4 and TCP
Server_Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Setting server socket option
Server_Socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Server will use IP and PORT to connect
Server_Socket.bind((IP, PORT))
# Start listening
Server_Socket.listen()
# List of sockets
Sockets_List = [Server_Socket]
# Using dictonary to create client list
Clients = {}
print(f'Listening for connections on {IP}:{PORT}')
# Receive message
def receive_message(Client_Socket):
try:
# Checking message length
Message_Header = Client_Socket.recv(Header_Length)
if not len(Message_Header):
return False
Message_Length = int(Message_Header.decode('utf-8'))
# Return header and data
return {'header': Message_Header, 'data': Client_Socket.recv(Message_Length)}
except:
return False
while True:
Read_Sockets, _, Exception_Sockets = select.select(Sockets_List, [], Sockets_List)
# Checking all sockets
for Connected_Socket in Read_Sockets:
# Checking new connection
if Connected_Socket == Server_Socket:
Client_Socket, Client_Address = Server_Socket.accept() # Accepting new connection
# Get username provided by the client
User = receive_message(Client_Socket)
# Client disconnect
if User is False:
continue
# If client did not disconnect, appending the connected list
Sockets_List.append(Client_Socket)
Clients[Client_Socket] = User
print('Accepted new connection from {}:{}, username:{}'.format(*Client_Address, User['data'].decode('utf-8')))
# Old connection
else:
# New message
Message = receive_message(Connected_Socket)
# Remove client from the list if disconnect
if Message is False:
print('Closed connection from:{}'.format(Clients[Connected_Socket]['data'].decode('utf-8')))
Sockets_List.remove(Connected_Socket)
del Clients[Connected_Socket]
continue
# Checking who sent the message
User = Clients[Connected_Socket]
print(f'Received message from {User["data"].decode("utf-8")}: {Message["data"].decode("utf-8")}')
# Broadcasting message
for Client_Socket in Clients:
# Filtering so that sender do not receive the message
if Client_Socket != Connected_Socket:
Client_Socket.send(User['header'] + User['data'] + Message['header'] + Message['data'])
# Exception handling
for Connected_Socket in Exception_Sockets:
Sockets_List.remove(Connected_Socket)
del Clients[Connected_Socket]
client.py
(client.py)
Client_Username = input("Username: ")
# Creating socket for client
Client_Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Client_Socket.connect((IP, PORT))
Client_Socket.setblocking(False)
# Sending username and header
Username = Client_Username.encode('utf-8')
Username_Header = f"{len(Username):^{Header_Length}}".encode('utf-8')
Client_Socket.send(Username_Header + Username)
while True:
# Waiting for message input
Message = input(f'{Client_Username} >>> ')
#Message = ""
# Sending message
if Message:
Message = Message.encode('utf-8')
Message_Header = f"{len(Message):^{Header_Length}}".encode('utf-8')
Client_Socket.send(Message_Header + Message)
# Checking for received messages from other users
try:
while True:
Username_Header = Client_Socket.recv(Header_Length)
# Closing connection
if not len(Username_Header):
print('Server Disconnected')
sys.exit()
# Decoding username and message
Username_Length = int(Username_Header.decode('utf-8'))
Username = Client_Socket.recv(Username_Length).decode('utf-8')
Message_Header = Client_Socket.recv(Header_Length)
Message_Length = int(Message_Header.decode('utf-8'))
Message = Client_Socket.recv(Message_Length).decode('utf-8')
print(f'{Username} >>> {Message}')
# Error handling
except IOError as ex:
if ex.errno != errno.EAGAIN and ex.errno != errno.EWOULDBLOCK:
print('IO Error: {}'.format(str(ex)))
sys.exit()
continue
# Error handling
except Exception as ex:
print('Error: '.format(str(e)))
sys.exit()
Now what I'm trying to implement is the client chat can have multiple channels, and a user would say something such as !join channel_name
this is in addition to a main channel.
(现在我要实现的是客户端聊天可以具有多个渠道,并且用户会说诸如!join channel_name
东西,这是对主要渠道的补充。)
There is multiple approaches I think would be possible, but I'm not 100% sure. (我认为可以采用多种方法,但是我不确定100%。)
One thing I might have to do is add an if
statement, so that if the user begins a phrase with !join
it would move said user to the different channel. (我可能要做的一件事是添加一个if
语句,这样,如果用户使用!join
开头一个短语,它将把该用户移至另一个通道。)
Another thing I'm stuck on is making having multiple-channels in the first place. (我坚持的另一件事是首先要具有多个渠道。)
Would I need to have multiple serves with different ports, or would there be another way to implement this using sockets? (我是否需要在不同的端口上使用多个服务,还是有另一种使用套接字实现此服务的方法?)
ask by GuardGoose translate from so 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…