tornado.tcpserver
— 基於 IOStream
的基本 TCP 伺服器¶
一個非阻塞、單執行緒的 TCP 伺服器。
- class tornado.tcpserver.TCPServer(ssl_options: Optional[Union[Dict[str, Any], SSLContext]] = None, max_buffer_size: Optional[int] = None, read_chunk_size: Optional[int] = None)[原始碼]¶
一個非阻塞、單執行緒的 TCP 伺服器。
要使用
TCPServer
,定義一個覆寫handle_stream
方法的子類別。 例如,一個簡單的回顯伺服器可以這樣定義from tornado.tcpserver import TCPServer from tornado.iostream import StreamClosedError class EchoServer(TCPServer): async def handle_stream(self, stream, address): while True: try: data = await stream.read_until(b"\n") await stream.write(data) except StreamClosedError: break
要使此伺服器提供 SSL 流量,請使用
ssl_options
關鍵字參數傳送ssl.SSLContext
物件。 為了與舊版本的 Python 相容,ssl_options
也可能是ssl.SSLContext.wrap_socket
方法的關鍵字參數字典。ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"), os.path.join(data_dir, "mydomain.key")) TCPServer(ssl_options=ssl_ctx)
TCPServer
初始化遵循以下三種模式之一listen
:單進程async def main(): server = TCPServer() server.listen(8888) await asyncio.Event.wait() asyncio.run(main())
雖然此範例不會自行建立多個進程,但當將
reuse_port=True
參數傳遞給listen()
時,您可以多次執行該程式以建立多進程服務。add_sockets
:多進程sockets = bind_sockets(8888) tornado.process.fork_processes(0) async def post_fork_main(): server = TCPServer() server.add_sockets(sockets) await asyncio.Event().wait() asyncio.run(post_fork_main())
add_sockets
介面更複雜,但它可以與tornado.process.fork_processes
一起使用,以執行一個多進程服務,其中所有工作進程都從單個父進程派生。 如果您想以bind_sockets
以外的方式建立監聽 socket,也可以在單進程伺服器中使用add_sockets
。請注意,當使用此模式時,任何涉及事件迴圈的操作都不能在
fork_processes
之前執行。-
server = TCPServer() server.bind(8888) server.start(0) # Forks multiple sub-processes IOLoop.current().start()
此模式已被棄用,因為它需要
asyncio
模組中自 Python 3.10 起已被棄用的介面。 在start
方法中建立多個進程的支援將在未來版本的 Tornado 中移除。
3.1 版新增:
max_buffer_size
引數。5.0 版變更: 已移除
io_loop
引數。- listen(port: int, address: Optional[str] = None, family: AddressFamily = AddressFamily.AF_UNSPEC, backlog: int = 128, flags: Optional[int] = None, reuse_port: bool = False) None [原始碼]¶
開始在給定的埠上接受連線。
此方法可以多次呼叫,以監聽多個埠。
listen
會立即生效;不需要後續呼叫TCPServer.start
。然而,如果事件迴圈尚未運行,則必須啟動它。所有引數的意義與
tornado.netutil.bind_sockets
中的相同。在 6.2 版本變更: 新增了
family
、backlog
、flags
和reuse_port
引數,以匹配tornado.netutil.bind_sockets
。
- add_sockets(sockets: Iterable[socket]) None [原始碼]¶
使此伺服器開始在給定的 socket 上接受連線。
sockets
參數是 socket 物件的清單,例如由bind_sockets
回傳的物件。add_sockets
通常與該方法和tornado.process.fork_processes
結合使用,以提供對多程序伺服器初始化的更大控制。
- add_socket(socket: socket) None [原始碼]¶
add_sockets
的單數版本。 採用單個 socket 物件。
- bind(port: int, address: Optional[str] = None, family: AddressFamily = AddressFamily.AF_UNSPEC, backlog: int = 128, flags: Optional[int] = None, reuse_port: bool = False) None [原始碼]¶
將此伺服器繫結到給定位址上的給定埠。
要啟動伺服器,請呼叫
start
。如果要在單個程序中運行此伺服器,則可以呼叫listen
作為bind
和start
呼叫序列的快捷方式。位址可以是 IP 位址或主機名稱。 如果是主機名稱,則伺服器將監聽與該名稱關聯的所有 IP 位址。位址可以是空字串或 None,以監聽所有可用的介面。 可以將 Family 設定為
socket.AF_INET
或socket.AF_INET6
,以限制為 IPv4 或 IPv6 位址,否則,如果可用,將同時使用兩者。backlog
引數的含義與socket.listen
相同。reuse_port
引數的含義與bind_sockets
相同。可以在
start
之前多次呼叫此方法,以監聽多個埠或介面。在 4.4 版本變更: 新增了
reuse_port
引數。在 6.2 版本變更: 新增了
flags
引數,以匹配bind_sockets
。自 6.2 版本起已棄用: 請使用
listen()
或add_sockets()
,而不是bind()
和start()
。
- start(num_processes: Optional[int] = 1, max_restarts: Optional[int] = None) None [原始碼]¶
在
IOLoop
中啟動此伺服器。預設情況下,我們在此程序中執行伺服器,並且不派生任何額外的子程序。
如果 num_processes 為
None
或 <= 0,我們會偵測此機器上可用的核心數量,並派生該數量的子程序。如果給定了 num_processes 且 > 1,我們會派生該特定數量的子程序。由於我們使用程序而不是執行緒,因此任何伺服器程式碼之間都沒有共享記憶體。
請注意,多個程序與自動重新載入模組(或
tornado.web.Application
的autoreload=True
選項,當debug=True
時預設為 True)不相容。當使用多個程序時,在呼叫TCPServer.start(n)
之前,無法建立或參考任何 IOLoop。Windows 上不支援 1 以外的
num_processes
值。max_restarts
引數會傳遞給fork_processes
。在 6.0 版本中變更: 新增
max_restarts
引數。自 6.2 版本起已棄用: 請使用
listen()
或add_sockets()
,而不是bind()
和start()
。