網站首頁 編程語言 正文
asyncore即是一個異步的socket封裝,特別是dispatcher類中包含了很多異步調用的socket操作方法。
模塊常見方法
這個模塊是socket的異步實現,此模塊中的一些類和方法:
asyncore.core
輸入一個輪詢循環直到通過計數或打開的通道已關閉
asyncore.dispatcher
dispatcher類是一個底層socket類的包裝對象。要使它更有用, 它有一部分事件處理方法被異步循環調用。否則它就是一個標準的非阻塞socket對象。
底層的事件在特定事件或特定的連接狀態告訴異步循環,某些高級事件發生了。例如, 我們要求一個socket連接到另一個主機。
- handle_connected():第一次讀或寫事件。
- handle_close():讀事件沒有數據可用。
- handle_accept():讀事件監聽一個socket。
- handle_read():在異步循環察覺到通道呼叫read()時調用。
- handle_write():在異步循環檢測到一個socket可寫時調用,例如:
def handle_write(self):
sent = self.send(self.buff)
self.buffer = self.buffer[sent:]
- handle_expt():當有OOB數據套接字(socket)連接,這幾乎永遠不會發生,因為OOB精細地支持和很少使用。
- handle_connect():當socket創建一個連接時調用。
- handle_close():當socket連接關閉時調用。
- handle_error():當引發一個異常并沒有其他處理時調用。
- handle_accept:當本地監聽通道與遠程端建立連接(被動連接)時調用。
- readable():每次在異步循環確定是否添加一個通道socket到讀事件列表時調用,默認都為True。
- writable():每次在異步循環確定是否添加一個通道socket到寫事件列表時調用, 默認為True。
- create_socket():與創建標準socket的時候相同。
- connect():與標準socket的端口設置是相同, 接受一個元組第一個參數為主機地址,第二個參數是端口號。
- send():向遠程端socket發送數據。
- recv():從遠程端socket讀取最多buffer_size的數據。一個空的字符串意味著從另一端通道已關閉。
- listen():監聽socket連接。
- bind():將socket綁定到地址。
- accept():接受一個連接, 必須綁定到一個socket和監聽地址。
- close():關閉socket。
asyncore.dispatcher_with_send
dispatcher子類添加了簡單的緩沖輸出功能用于簡單的客戶,更復雜的使用asynchat.async_chat。
asyncore.file_dispatcher
file_dispatcher需要一個文件描述符或文件對象地圖以及一個可選的參數,包裝,使用調查()或循環()函數。如果提供一個文件對象或任何fileno()方法,該方法將調用和傳遞到file_wrapper構造函數。可用性:UNIX。
asyncore.file_wrapper
file_wrapper需要一個整數文件描述符并調用os.dup()復制處理,這樣原來的處理可能是獨立于file_wrapper關閉。這個類實現足夠的方法來模擬一個套接字使用file_dispatcher類。可用性:UNIX。
asyncore 實例
一個http client的實現
import socket
import asyncore
class Client(asyncore.dispatcher):
?? ?def __init__(self, host, path):
?? ??? ?asyncore.dispatcher.__init__(self)
?? ??? ?self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
?? ??? ?self.connect((host,80))
?? ??? ?self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path
?? ?
? ? def handle_connect(self):
?? ??? ?pass
?? ?
? ? def handle_close(self):
?? ??? ?self.close()
?? ?
? ? def handle_read(self):
?? ??? ?print self.recv(8192)
?? ?
? ? def writable(self):
?? ??? ?return (len(self.buffer) >0)
?? ?
? ? def handle_write(self):
?? ??? ?sent= self.send(self.buffer)
?? ??? ?self.buffer = self.buffer[sent:]
?? ??? ?client= Client('www.python.org','/')
?? ??? ?asyncore.loop()
服務器接受連接和分配任務
import socket
import asyncore
class EchoHandler(asyncore.dispatcher_with_send):
?? ?
? ? def handle_read(self):
?? ??? ?data= self.recv(8192)
? ? ? ? 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_add()
? ? ? ? self.bind((host, port))
? ? ? ? self.listen(5)
? ? def handle_accept(self):
? ? ? ? pair= self.accept()
? ? ? ? if pair is not None:
? ? ? ? sock, addr= pair
? ? ? ? print 'Incoming connection from %s' % repr(addr)
? ? ? ? handler= EchoHandler(sock)
? ? ? ? server= EchoServer('localhost',8080)
? ? ? ? asyncore.loop()
利用asyncore的端口映射(端口轉發)
import socket,asyncore
class forwarder(asyncore.dispatcher):
? ? def __init__(self, ip, port, remoteip,remoteport,backlog=5):
? ? ? ? asyncore.dispatcher.__init__(self)
? ? ? ? self.remoteip=remoteip
? ? ? ? self.remoteport=remoteport
? ? ? ? self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
? ? ? ? self.set_reuse_addr()
? ? ? ? self.bind((ip,port))
? ? ? ? self.listen(backlog)
? ? def handle_accept(self):
? ? ? ? conn, addr= self.accept()
? ? ? ? # print '--- Connect --- '
? ? ? ? sender(receiver(conn),self.remoteip,self.remoteport)
class receiver(asyncore.dispatcher):
? ? def __init__(self,conn):
? ? ? ? asyncore.dispatcher.__init__(self,conn)
? ? ? ? self.from_remote_buffer=''
? ? ? ? self.to_remote_buffer=''
? ? ? ? self.sender=None
? ? ? ??
? ? def handle_connect(self):
? ? ? ? pass
? ? def handle_read(self):
? ? ? ? read= self.recv(4096)
? ? ? ? # print '%04i -->'%len(read)
? ? ? ? self.from_remote_buffer+= read
? ? def writable(self):
? ? ?? ?return (len(self.to_remote_buffer) >0)
? ? def handle_write(self):
?? ??? ?sent= self.send(self.to_remote_buffer)
? ? ? ? # print '%04i <--'%sent
? ? ? ? self.to_remote_buffer= self.to_remote_buffer[sent:]
? ? def handle_close(self):
? ? ? ? self.close()
? ? ? ? if self.sender:
?? ??? ??? ?self.sender.close()
class sender(asyncore.dispatcher):
? ? def __init__(self, receiver, remoteaddr,remoteport):
? ? ? ? asyncore.dispatcher.__init__(self)
? ? ? ? self.receiver=receiver
? ? ? ? receiver.sender=self
? ? ? ? self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
? ? ? ? self.connect((remoteaddr, remoteport))
? ? def handle_connect(self):
? ? ?? ?pass
? ? def handle_read(self):
? ? ? ? read= self.recv(4096)
? ? ? ? # print '<-- %04i'%len(read)
? ? ? ? self.receiver.to_remote_buffer+= read
? ? def writable(self):
? ? ?? ?return (len(self.receiver.from_remote_buffer) >0)
? ? def handle_write(self):
?? ??? ?sent= self.send(self.receiver.from_remote_buffer)
? ? ?? ?# print '--> %04i'%sent
? ? ?? ?self.receiver.from_remote_buffer= self.receiver.from_remote_buffer[sent:]
? ? def handle_close(self):
? ? ? ? self.close()
? ? ? ? self.receiver.close()
? ??
? ? if __name__=='__main__':
? ? ? ? import optparse
? ? ? ? parser= optparse.OptionParser()
? ? ? ??
? ? ? ? parser.add_option(
? ? ? ? '-l','--local-ip',
? ? ? ? dest='local_ip',default='127.0.0.1',
? ? ? ? help='Local IP address to bind to')
? ? ? ??
? ? ? ? parser.add_option(
? ? ? ? '-p','--local-port',
? ? ? ? type='int',dest='local_port',default=80,
? ? ? ? help='Local port to bind to')
? ? ? ??
? ? ? ? parser.add_option(
? ? ? ? '-r','--remote-ip',dest='remote_ip',
? ? ? ? help='Local IP address to bind to')
? ? ? ? parser.add_option(
? ? ? ? '-P','--remote-port',
? ? ? ? type='int',dest='remote_port',default=80,
? ? ? ? help='Remote port to bind to')
? ? ? ? options, args= parser.parse_args()
? ? ? ? forwarder(options.local_ip,options.local_port,options.remote_ip,options.remote_port)
? ? ? ? asyncore.loop()
原文鏈接:https://blog.csdn.net/qq_41962612/article/details/128712838
相關推薦
- 2022-12-23 react數據管理機制React.Context源碼解析_React
- 2022-03-20 .NET?6開發TodoList應用之實現DELETE請求與HTTP請求冪等性_實用技巧
- 2022-07-01 詳解如何在Go語言中調用C源代碼_Golang
- 2023-11-11 Flask 表單form.validate_on_submit()什么情況下會是false——解決辦
- 2022-07-13 二叉樹的創建和前序,中序,后序遍歷(詳細)
- 2022-10-13 Python?數據分析教程探索性數據分析_python
- 2023-11-17 RuntimeError: a view of a leaf Variable that requi
- 2023-03-27 Android進階之從IO到NIO的模型機制演進_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支