我想在 python (Python 3.9.9) 中使用 asyncio 在一個腳本中運行兩個簡單的 TCP 服務器。顯然,每臺服務器都運行在不同的埠上。我在使用正確的語法來同時創建和啟動兩個服務器時遇到問題。以下是我到目前為止的內容,但我不斷收到 RuntimeError: This event loop is already running。
我已經看到了僅使用函式和 loop.start_server 的方法,但我需要使用 asyncio.Protocol 類,以便可以訪問 conection_made 和 connection_lost 的回呼。我不知道我是否需要 loop.create_server 或其他語法,但無論我在做什么顯然都是錯誤的。那么如何使用 asyncio.Protocol 做到這一點?
注意:這兩個服務器都意味著永遠運行。客戶端可以連接和斷開連接,但服務器應該永遠運行。
###############################################################################
# echoserver.py
# Simple code to run EchoServer on two ports simultaneously
###############################################################################
import asyncio
FIRST_PROCESS_PORT =14401
SECOND_PROCESS_PORT =14402
class MyLogger(object):
def info(self,s):
print(s)
logger = MyLogger()
#
# EchoServer class
#
class EchoServer(asyncio.Protocol):
def __init__(self):
self.client_info=None
# Begin asyncio.Protocol overrides
def connection_made(self,transport):
self.transport = transport
self.client_info = self.transport.get_extra_info('peername')
logger.info('connection_made from: %s' % self.client_info)
def connection_lost(self, reason):
logger.info( 'connection_lost: %s | %s' % (self.client_info, reason))
def data_received(self,data):
print("Received: %s" % str(data))
self.transport.write(data)
async def main():
global server1
global server2
loop = asyncio.get_running_loop()
factory1 = await loop.create_server(lambda: EchoServer(),"localhost",FIRST_PROCESS_PORT)
factory2 = await loop.create_server(lambda: EchoServer(),"localhost",SECOND_PROCESS_PORT)
server1 = await loop.run_until_complete(factory1)
server2 = await loop.run_until_complete(factory2)
async with server1, server2:
await asyncio.gather(server1.run_forever(),server2.run_forever())
print("Main done");
###################
# main code here
###################
if __name__ == "__main__":
asyncio.run(main())
print("Done");
uj5u.com熱心網友回復:
我做了一些簡單的重新安排,使服務器在兩個埠上作業:
###############################################################################
# echoserver.py
# Simple code to run EchoServer on two ports simultaneously
###############################################################################
import asyncio
FIRST_PROCESS_PORT = 14401
SECOND_PROCESS_PORT = 14402
class MyLogger(object):
def info(self, s):
print(s)
logger = MyLogger()
class EchoServer(asyncio.Protocol):
def __init__(self):
self.client_info = None
# Begin asyncio.Protocol overrides
def connection_made(self, transport):
self.transport = transport
self.client_info = self.transport.get_extra_info("peername")
logger.info(f"connection_made from: {self.client_info}")
def connection_lost(self, reason):
logger.info("connection_lost: %s | %s" % (self.client_info, reason))
def data_received(self, data):
print("Received: %s" % str(data))
self.transport.write(data)
async def main():
loop = asyncio.get_running_loop()
server1 = await loop.create_server(
lambda: EchoServer(), "0.0.0.0", FIRST_PROCESS_PORT
)
server2 = await loop.create_server(
lambda: EchoServer(), "0.0.0.0", SECOND_PROCESS_PORT
)
# serve forever
async with server1, server2:
while True:
await asyncio.sleep(3600)
if __name__ == "__main__":
asyncio.run(main())
這將在所有介面 ( 0.0.0.0) 上創建兩個埠,但您可以將其更改為localhost.
如果您在其他終端上運行:
echo "Hello World" | nc -N <your IP address> 14401
echo "Hello World" | nc -N <your IP address> 14402
服務器回應:
connection_made from: ('XXX', 41760)
Received: b'Hello World\n'
connection_lost: ('XXX', 41760) | None
connection_made from: ('XXX', 32872)
Received: b'Hello World\n'
connection_lost: ('XXX', 32872) | None
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/479029.html
