使用epoll 实现客户端群聊
时间: 2023-11-09 10:08:48 浏览: 85
使用epoll的聊天程序
首先,需要了解什么是 epoll。
epoll 是 Linux 内核提供的一种 I/O 事件通知机制,可以用来代替传统的 select/poll 事件通知方式。epoll 的优势在于:
1. 支持水平触发和边缘触发两种模式;
2. 没有最大并发连接数限制,能够处理大量的连接和并发请求;
3. 效率更高,因为 epoll 只需要在进程启动时做一次内存映射,而不需要像 select/poll 那样遍历所有的文件描述符。
接下来,我们来实现客户端群聊功能。
首先,需要创建一个服务端,接收客户端的连接请求,并将客户端的套接字加入到 epoll 监听列表中。当有客户端发送消息时,服务端会接收到消息,并将消息广播给所有连接的客户端。
以下是代码实现:
```python
import socket
import select
# 创建 TCP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定地址和端口
server_socket.bind(('127.0.0.1', 8888))
# 监听连接请求
server_socket.listen()
# 创建 epoll 对象
epoll = select.epoll()
# 将服务端套接字加入到 epoll 监听列表中
epoll.register(server_socket.fileno(), select.EPOLLIN)
# 定义客户端套接字字典
clients = {}
while True:
# 等待 epoll 事件通知
events = epoll.poll()
for fileno, event in events:
# 处理服务端套接字的连接请求
if fileno == server_socket.fileno():
client_socket, client_address = server_socket.accept()
print(f'New client {client_address} connected!')
# 将客户端套接字加入到 epoll 监听列表中
epoll.register(client_socket.fileno(), select.EPOLLIN)
# 将客户端套接字加入到字典中
clients[client_socket.fileno()] = client_socket
# 处理客户端套接字的消息
elif event & select.EPOLLIN:
client_socket = clients[fileno]
message = client_socket.recv(1024)
# 如果客户端断开连接,将其从 epoll 监听列表和字典中删除
if not message:
print(f'Client {client_socket.getpeername()} disconnected!')
epoll.unregister(fileno)
del clients[fileno]
continue
# 广播消息给所有连接的客户端
for client_fileno, client_socket in clients.items():
if client_fileno != fileno:
client_socket.send(message)
# 关闭 epoll 对象和服务端套接字
epoll.close()
server_socket.close()
```
在客户端,需要先连接到服务端,然后发送消息给服务端。客户端接收到服务端广播的消息后,将消息打印出来即可。
以下是客户端代码实现:
```python
import socket
import threading
# 创建 TCP 套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务端
client_socket.connect(('127.0.0.1', 8888))
# 定义发送消息的函数
def send_message():
while True:
message = input()
client_socket.send(message.encode())
# 定义接收消息的函数
def receive_message():
while True:
message = client_socket.recv(1024)
print(message.decode())
# 创建发送消息和接收消息的线程
send_thread = threading.Thread(target=send_message)
receive_thread = threading.Thread(target=receive_message)
# 启动线程
send_thread.start()
receive_thread.start()
# 等待线程结束
send_thread.join()
receive_thread.join()
# 关闭客户端套接字
client_socket.close()
```
运行以上代码,就可以实现客户端之间的群聊功能了。
阅读全文