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()