32系统只能1024个链接 64位 2048个python
采用轮询机制,当并发大的时候,就会崩了缓存
POLL只是突破了链接的限制并发
上代码:app
from socket import * import select def main(): # 建立对象 tcp_server = socket(AF_INET, SOCK_STREAM) # 绑定地址 tcp_server.bind(('', 8888)) # 将主动模式设置为被动模式 tcp_server.listen(5) # 初始化一个列表 server_lists = [tcp_server] # 将初始socket对象添加至列表中 while True: sockets, _, _ = select.select(server_lists, [], []) for obj in sockets: if obj == tcp_server: # 建立新的链接 new_socket, client_info = obj.accept() # 将新的new_socket对象添加至列表 server_lists.append(new_socket) # 打印链接信息 print(f'来自{client_info} 链接成功!') else: # 接收数据 raw_data = obj.recv(1024) # 注意: 这个地方不能使用死循环,不然会致使阻塞状况,同一时总能一个客户端通讯,其余客户端将阻塞排队中,当前面断开是,后面的讲能够继续通讯 if raw_data: # 打印数据 print(f'接收到数据: {raw_data.decode("gb2312")}') else: # 内容为空 移出链接信息 server_lists.remove(obj) obj.close() if __name__ == '__main__': main()
poll已实现无数链接 轮询socket
epoll 改为事件通知tcp
只能在Linux上使用 不能在window使用高并发
上代码:code
from socket import * import select def main(): # 建立对象 tcp_socket = socket(AF_INET, SOCK_STREAM) # 绑定地址 tcp_socket.bind(('', 8888)) # 将主动模式设置为被动模式 tcp_socket.listen(5) # 建立epoll epoll = select.epoll() # 把被动套接字添加至监听读状态 epoll.register(tcp_socket.fileno(), select.EPOLLIN) # 声明一个字典 用来存新建立套接字 new_sockets = {} client_infos = {} while True: epoll_list = epoll.poll() for fd, _ in epoll_list: if fd == tcp_socket.fileno(): # 建立新的链接 new_socket, client_info = tcp_socket.accept() # 把新对象添加至监听 epoll.register(new_socket.fileno(), select.EPOLLIN) # 添加至字典 new_sockets[new_socket.fileno()] = new_socket client_infos[client_info] = client_info print(f'来自{client_info} 链接成功!') else: # 接收数据 raw_data = new_sockets[fd].recv(1024) # 判断是否有数据 if raw_data: print(f'来自{client_info}的信息: {raw_data.decode("gb2312")}') else: print('客户端已断开!') # 客户端已关闭 new_sockets[fd].close() # 注销监听队列 epoll.unregister(fd) # 移除字典 del new_sockets[fd] del client_infos if __name__ == '__main__': main()