Python非同步通訊模組asyncore

小屋子大俠發表於2017-04-18

Python非同步通訊模組asyncore

介紹

Python的asyncore模組提供了以非同步的方式寫入套接字服務的客戶端和伺服器的基礎結構。

模組主要包括:

  • asyncore.loop(…) - 用於迴圈監聽網路事件。loop()函式負責檢測一個字典,字典中儲存dispatcher的例項。

  • asyncore.dispatcher類 - 一個底層套接字物件的簡單封裝。這個類有少數由非同步迴圈呼叫的,用來事件處理的函式。

    • dispatcher類中的writable()和readable()在檢測到一個socket可以寫入或者資料到達的時候被呼叫,並返回一個bool值,決定是否呼叫handle_read或者handle_write。
  • asyncore.dispatcher_with_send類 - 一個 dispatcher的子類,新增了簡單的緩衝輸出能力,對簡單的客戶端很有用。

例子

下面看一個簡單的例子

import time
import asyncore
import socket
import threading


class EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(1024)
        if data:
            self.send(data)

class EchoServer(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accept(self):
        conn, addr = self.accept()
        print 'Incoming connection from %s' % repr(addr)
        self.handler = EchoHandler(conn)

class EchoClient(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.messages = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((host, port))

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print self.recv(1024)

    def writable(self):
        return (len(self.messages) > 0)

    def handle_write(self):
        if len(self.messages) > 0: 
            self.send(self.messages.pop(0))

class EchoServerThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        server = EchoServer('localhost', 9999)
        asyncore.loop()

class EchoClientThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        client = EchoClient('localhost', 9999)
        asyncore.loop()

EchoServerThread().start()
time.sleep(2)
EchoClientThread().start()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • EchoServer - 響應伺服器端程式,負責監聽一個埠,並響應客戶端傳送的訊息然後原樣返回給客戶端。其中handle_accept()方法定義當一個連線到來的時候要執行的操作,這裡指定了使用一個Handler來出來傳送來的資料。

  • EchoHandler - 伺服器端資料響應類,接收資料並把資料原樣發回。

  • EchoClient - 響應服務客戶端程式,負責連線響應伺服器。其中

    • messages - 定義了一個要傳送的訊息列表,每次傳送一個訊息,知道列表為空為止。

    • handle_read() - 處理接收到的資料,這裡把收到的資料列印的終端上。

    • writable() - 判斷是否有資料可以向伺服器端傳送。

    • handle_write() - 當writable()函式返回True時,寫入資料。

  • EchoServerThread - 用來啟動伺服器端程式的執行緒。

  • EchoClientThread - 用來啟動客戶端端程式的執行緒。

測試

執行上面的測試程式碼,可以看到伺服器和客戶端建立了連線後,響應了客戶端傳送來的10個數字,然後關閉了連線。

Incoming connection from ('127.0.0.1', 51424)
1
2
3
4
5
6
7
8
9
10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

轉載請以連結形式標明本文地址 
本文地址:http://blog.csdn.net/kongxx/article/details/51158775

相關文章