欢迎访问宙启技术站
智能推送

Python编程中使用Select()函数实现即时聊天功能

发布时间:2023-12-27 17:49:31

即时聊天是指在网络上进行实时的文本交流的功能。Python中可以使用select()函数来实现即时聊天功能,select()函数可以监听多个文件描述符(包括Socket对象),并在有I/O事件发生时进行相应的处理。

下面是使用select()函数实现即时聊天功能的例子:

import select
import socket
import sys

def chat_server():
    # 创建一个TCP套接字并绑定到指定的IP地址和端口
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('localhost', 8888))
    server_socket.listen(5)
    
    # 保存所有连接进来的客户端套接字
    client_sockets = [server_socket]
    
    while True:
        # 使用select()函数监听客户端套接字和标准输入
        read_sockets, _, _ = select.select(client_sockets, [], [])
        
        # 遍历有I/O事件发生的套接字
        for sock in read_sockets:
            # 如果是服务器套接字有新连接进来
            if sock == server_socket:
                client_socket, addr = server_socket.accept()
                client_sockets.append(client_socket)
                print('New client connected:', addr)
            # 如果是客户端套接字有数据可读
            else:
                try:
                    data = sock.recv(4096).decode()
                    if data:
                        print('Received:', data)
                        broadcast_data(sock, data)
                    else:
                        # 如果客户端关闭了连接
                        sock.close()
                        client_sockets.remove(sock)
                except:
                    continue

def broadcast_data(sender_socket, message):
    # 向除了发送者以外的所有客户端发送消息
    for sock in client_sockets:
        if sock != server_socket and sock != sender_socket:
            try:
                sock.send(message.encode())
            except:
                sock.close()
                client_sockets.remove(sock)
                continue

def chat_client():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('localhost', 8888))
    
    while True:
        # 使用select()函数监听标准输入和服务器套接字
        read_sockets, _, _ = select.select([sys.stdin, client_socket], [], [])
        
        # 遍历有I/O事件发生的套接字
        for sock in read_sockets:
            # 如果是标准输入可读
            if sock == sys.stdin:
                message = sys.stdin.readline().strip()
                client_socket.send(message.encode())
            # 如果是服务器套接字有数据可读
            else:
                data = sock.recv(4096).decode()
                if data:
                    print('Received:', data)

if __name__ == '__main__':
    if len(sys.argv) == 2 and sys.argv[1] == 'server':
        chat_server()
    else:
        chat_client()

在上面的例子中,我们创建了一个简单的即时聊天程序,其中包含了一个简单的服务器端和一个客户端。服务器端监听主机的某个端口,并接受连接进来的客户端,客户端连接到服务器端后可以发送消息给服务器端,并接收其他客户端发送的消息。

服务器端和客户端都使用了select()函数来监听多个套接字,并在有数据可读时进行相应的处理。服务器端监听了客户端套接字的连接进来以及客户端套接字的数据可读事件,并分别进行相应的处理。客户端监听了标准输入的可读事件和服务器端套接字的数据可读事件,并分别进行相应的处理。

在服务器端,当有新的客户端连接进来时,将其套接字添加到客户端套接字列表中,并向其他客户端广播新客户端的连接信息。当客户端套接字有数据可读时,将其接收到的数据广播给其他客户端。

在客户端,用户可以输入消息并发送给服务器端,同时也可以接收其他客户端发送的消息并打印出来。当标准输入有数据可读时,将其读取的数据发送给服务器端。当服务器端套接字有数据可读时,将其接收到的数据打印出来。

通过这个例子,我们可以了解到如何使用select()函数来实现即时聊天功能,通过监听多个套接字,实时处理各个套接字的I/O事件,从而实现即时聊天功能。