下面是基于Python socket实现简易网络聊天室的完整攻略。
步骤一:实现基本的客户端和服务端
首先我们需要实现简单的客户端和服务端,可以让客户端发送消息给服务端,并让服务端把消息广播给所有的客户端。
客户端
import socket
import threading
IP = '127.0.0.1'
PORT = 1234
def send_message():
while True:
message = input('')
client_socket.sendall(message.encode('utf-8'))
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
threading.Thread(target=send_message).start()
while True:
data = client_socket.recv(1024)
print(data.decode('utf-8'))
服务端
import socket
import threading
IP = '127.0.0.1'
PORT = 1234
clients = []
def send_all(message, sender):
for client in clients:
if client != sender:
client.sendall(message)
def handle_client(client, address):
clients.append(client)
while True:
data = client.recv(1024)
send_all(data, client)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((IP, PORT))
server_socket.listen()
while True:
client, address = server_socket.accept()
threading.Thread(target=handle_client, args=(client, address)).start()
步骤二:添加用户名
接下来我们要让客户端能够设置一个用户名,显示在发送消息的前面。
我们可以在客户端和服务端加上一个username
字段,这里我们用JSON格式来传递客户端和服务端之间的消息。
修改后的代码如下:
客户端
import socket
import threading
import json
IP = '127.0.0.1'
PORT = 1234
def send_message():
while True:
message = input('')
data = {'username': username, 'message': message}
client_socket.sendall(json.dumps(data).encode('utf-8'))
username = input('Enter your username: ')
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
threading.Thread(target=send_message).start()
while True:
data = client_socket.recv(1024)
data = json.loads(data.decode('utf-8'))
print(f'{data["username"]}: {data["message"]}')
服务端
import socket
import threading
import json
IP = '127.0.0.1'
PORT = 1234
clients = []
def send_all(data, sender):
for client in clients:
if client != sender:
client.sendall(json.dumps(data).encode('utf-8'))
def handle_client(client, address):
username = None
while True:
data = client.recv(1024)
data = json.loads(data.decode('utf-8'))
if username is None:
username = data['username']
clients.append(client)
send_all(data, client)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((IP, PORT))
server_socket.listen()
while True:
client, address = server_socket.accept()
threading.Thread(target=handle_client, args=(client, address)).start()
现在客户端在发送消息的时候会自动带上当前的用户名。
示例一:Ethan向聊天室中发送一条消息
Ethan 的客户端:
Enter your username: Ethan
Hello this is Ethan.
聊天室中其他客户端:
Ethan: Hello this is Ethan.
示例二:Mike向聊天室中发送一条消息
Mike 的客户端:
Enter your username: Mike
Hi, everyone!
聊天室中其他客户端:
Ethan: Hello this is Ethan.
Mike: Hi, everyone!
步骤三:支持私聊
最后我们再让聊天室支持私聊功能。
我们可以在客户端发送消息时,添加一个to
字段,表示发给谁;在服务端收到消息时,判断一下是广播还是私聊,然后分别进行处理。
具体实现如下:
客户端
import socket
import threading
import json
IP = '127.0.0.1'
PORT = 1234
def send_message():
while True:
message = input('')
data = {'username': username, 'message': message, 'to': to}
client_socket.sendall(json.dumps(data).encode('utf-8'))
username = input('Enter your username: ')
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
threading.Thread(target=send_message).start()
while True:
data = client_socket.recv(1024)
data = json.loads(data.decode('utf-8'))
if data['to'] == username or data['to'] == 'all':
print(f'{data["username"]}: {data["message"]}')
服务端
import socket
import threading
import json
IP = '127.0.0.1'
PORT = 1234
clients = []
def send_all(data, sender):
for client in clients:
if client != sender:
client.sendall(json.dumps(data).encode('utf-8'))
def handle_client(client, address):
username = None
while True:
data = client.recv(1024)
data = json.loads(data.decode('utf-8'))
if username is None:
username = data['username']
clients.append(client)
if data['to'] == 'all':
send_all(data, client)
else:
for c in clients:
if c != client and c.getpeername() == data['to']:
c.sendall(json.dumps(data).encode('utf-8'))
break
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((IP, PORT))
server_socket.listen()
while True:
client, address = server_socket.accept()
threading.Thread(target=handle_client, args=(client, address)).start()
现在客户端发送私聊消息时,需要在消息前加上@
和用户名,例如@Ethan Hi
,表示把消息发给 Ethan。
示例三:Ethan向聊天室中发送一条私聊消息
Ethan 的客户端:
Enter your username: Ethan
@Mike Hi Mike, how are you doing?
聊天室中其他客户端:
Ethan: @Mike Hi Mike, how are you doing?
Mike 的客户端上不会出现这条消息,因为这是一条私聊消息,只有 Mike 和 Ethan 能看到。
示例四:Mike向聊天室中发送一条私聊消息
Mike 的客户端:
Enter your username: Mike
@Ethan Hi Ethan, are you busy now?
聊天室中其他客户端:
Ethan: @Mike Hi Ethan, are you busy now?
以上就是基于Python socket实现简易网络聊天室的完整攻略,希望能对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于Python socket实现简易网络聊天室 - Python技术站