我一直在遵循有关如何使用python 3使用套接字进行多客户端聊天的教程。到目前为止,我已经开始使用它了。这是我的代码:
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_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()
现在我要实现的是客户端聊天可以具有多个渠道,并且用户会说诸如!join channel_name
这样的内容是对主要渠道的补充。我认为可以采用多种方法,但是我不确定100%。
我可能要做的一件事是添加一个if
语句,这样,如果用户以!join
开头一个短语,它将把该用户移至另一个频道。
我坚持的另一件事是首先要具有多个渠道。我是否需要在不同的端口上使用多个服务,还是有另一种使用套接字实现此服务的方法?