Pythonネットワークプログラミングepollの使用



Python Network Programming Epoll Use



上記のことから、epollは選択モデルとポーリングモデルの改善であり、ネットワークプログラミングのパフォーマンスを改善し、大規模な同時要求のC / Sアーキテクチャで広く使用されています。

1、トリガーモード:



エッジトリガー/水平トリガー、Unix / Linuxオペレーティングシステムのみ

2、回路図



3、一般的な手順

  1. epollオブジェクトを作成する-epollオブジェクトを作成する
  2. 特定のソケットで特定のイベントを監視するようにepollオブジェクトに指示します-指定されたソケットで指定されたイベントをリッスンするようにepollオブジェクトに指示します
  3. epollオブジェクトに最後のクエリ以降に指定されたイベントが発生した可能性のあるソケットを尋ねる-最後のクエリ以降にソケットから発生した特定のイベントをepollオブジェクトに尋ねます
  4. それらのソケットでいくつかのアクションを実行します-これらのソケットでいくつかの操作を実行します
  5. 監視するソケットおよび/またはイベントのリストを変更するようにepollオブジェクトに指示します-epollオブジェクトに指示し、ソケットリストおよび/またはイベントを変更し、監視します
  6. 完了するまで手順3〜5を繰り返します-完了するまで手順3〜5を繰り返します
  7. epollオブジェクトを破棄します-epollオブジェクトを破棄します

4、関連する使用法



インポート選択インポート選択モジュール

Epoll = select.epoll()はepollオブジェクトを作成します

Epoll.register(ファイルハンドル、イベントタイプ)監視するファイルハンドルとイベントを登録します

イベントタイプ:

select.EPOLLIN読み取り可能イベント

select.EPOLLOUT書き込み可能イベント

select.EPOLLERRエラーイベント

select.EPOLLHUPクライアント切断イベント

Epoll.unregister(ファイルハンドル)ファイルハンドルを破棄します

Epoll.poll(timeout)ファイルハンドルが変更されると、リスト、タイムアウトの形式でユーザープロセスに報告されます。

タイムアウト期間のデフォルトは-1です。つまり、1として指定されている場合は、ファイルハンドルが変更されるまで待機します。

次に、epollは現在のファイルハンドルの変更を1秒ごとに報告し、変更がない場合はnullを返します。

Epoll.fileno()は、epoll制御ファイル記述子を返します(epoll制御ファイル記述子を返します)

Epoll.modfiy(fineno、event)finenoはファイル記述子です。eventはイベントタイプです。役割は、ファイル記述子に対応するイベントを変更することです。

Epoll.fromfd(fileno)は、指定されたファイル記述子からepollオブジェクトを作成します

Epoll.close()は、epollオブジェクトの制御ファイル記述子を閉じます

例は次のとおりです。

クライアント:

#!/usr/bin/env python #-*- coding:utf-8 -*- import socket #Create client socket object clientsocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # IP address and port number tuple server_address = ('127.0.0.1',8888) #Client connection specified IP address and port number clientsocket.connect(server_address) while True: #Input data data = raw_input('please input:') # clientsocket.sendall(data) # server_data = clientsocket.recv(1024) Print 'Data received by the client: 'server_data #Close client socket clientsocket.close()

サービスターミナル:

#!/usr/bin/env python #-*- coding:utf-8 -*- import socket import select import Queue #Create socket object serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IP address reuse serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #ipaddress and port number server_address = ('127.0.0.1', 8888) #binding IP address serversocket.bind(server_address) # , and set the maximum number of connections serversocket.listen(10) Print 'The server started successfully, listening for IP:', server_address #Server-side setting is non-blocking serversocket.setblocking(False) #overtime time timeout = 10 #Create an epoll event object, and add events to be monitored later. epoll = select.epoll() # Server listens to fd to wait for read event collection epoll.register(serversocket.fileno(), select.EPOLLIN) #Save a dictionary that connects client messages in the format {} message_queues = {} #File handle to the dictionary of the corresponding object, the format is {handle: object} fd_to_socket = {serversocket.fileno():serversocket,} while True: Print 'waiting for an active connection...' # Poll the registered event collection, the return value is [(file handle, corresponding event), (...), ....] events = epoll.poll(timeout) if not events: Print 'epoll timeout no active connection, re-polling...' continue Print ' ', len(events), 'a new event, start processing...' for fd, event in events: socket = fd_to_socket[fd] #If the active socket is the current server socket, it means there is a new connection. if socket == serversocket: connection, address = serversocket.accept() Print 'new connection:' , address #New connection socket set to non-blocking connection.setblocking(False) #Register new connection fd to the collection of events to be read epoll.register(connection.fileno(), select.EPOLLIN) #Save the newly connected file handle and object to the dictionary fd_to_socket[connection.fileno()] = connection #The newly connected object is the key value, the value is stored in the queue, and the information of each connection is saved. message_queues[connection] = Queue.Queue() #Close event elif event & select.EPOLLHUP: print 'client close' #Logout the client's file handle in epoll epoll.unregister(fd) #Close the client's file handle fd_to_socket[fd].close() #Delete information related to closed clients in the dictionary del fd_to_socket[fd] #readable event elif event & select.EPOLLIN: #Receive data data = socket.recv(1024) if data: Print 'receive data:', data, 'client:', socket.getpeername() # put data into the dictionary of the corresponding client message_queues[socket].put(data) #Modify the connection to the message waiting to write the event collection (that is, after the corresponding client receives the message, modify its fd and add it to the write event collection) epoll.modify(fd, select.EPOLLOUT) #Writeable event elif event & select.EPOLLOUT: try: #Get the corresponding client information from the dictionary msg = message_queues[socket].get_nowait() except Queue.Empty: print socket.getpeername() , ' queue empty' #Modify the file handle as a read event epoll.modify(fd, select.EPOLLIN) else : Print 'send data:', data, 'client:', socket.getpeername() #send data socket.send(msg) #Unregister the server file handle in epoll epoll.unregister(serversocket.fileno()) # epoll epoll.close() # ServerSocket serversocket.close() Server code