python的asyncio庫,事件迴圈,直接使用socket物件
阿新 • • 發佈:2021-01-08
python的asyncio庫,事件迴圈,直接使用socket物件,
loop.sock_recv(s:套接字,1024),套接字超時設定
socket.setdefaulttimeout(5) #設定連線等待時間
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(5) #設定recv()等待時間
業務邏輯和原始碼
研究loop.sock_recv()出現了一些奇怪的問題,希望不吝賜教,共同進步,感激
webserver.py,
實現功能:每來一個連線就建立一個執行緒,子執行緒sock,等待3秒,傳送資料
import socket
import threading
def threadsend(s,ad):
print(ad)
time.sleep(3)
s.send("hello!!!".encode())
s.close()
#start read
l=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
l.bind(("127.0.0.1",12346))
l.listen(5)
while 1:
s,ad=l.accept()
s.settimeout(5)
run=threading. Thread(target=threadsend,args=(s,ad))
run.start()
l.close()
async_client.py
實現功能:建立一個事件迴圈,主程式main()連續建立4個連線sock,投給子程式去處理,接收資訊。
await asyncio.sleep(0) 讓出程式執行權
import socket
import asyncio
import time
async def async_recv(s,i):
print(s)
loop=asyncio.get_running_loop()
print("第{}個協程{}接收資料" .format(i,time.time()))
da = await loop.sock_recv(s, 1024)
#await asyncio.sleep(0)
print("第{}個協程{}接收資料".format(i,time.time()))
print(da.decode()+str(i))
async def main():
for i in range(0,5):
socket.setdefaulttimeout(5)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.settimeout(5)
# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# s.setblocking(False)
s.connect(("127.0.0.1",12346))
asyncio.ensure_future(async_recv(s,i))
await asyncio.sleep(0)
print("主程式執行完畢")
#start read
loop=asyncio.get_event_loop()
loop.run_until_complete(main())
問題:
在執行da=await loop.sock_recv(s,1024)
時,該子程式讓出執行權,
按道理應該在接收到資料後,獲得執行權繼續執行
可目前遇到問題是,async_recv()無法等待接收資料,即接收 webserver.py的time.time(3)
3秒後,傳送的資料。
難道time.time(3)
伺服器延遲傳送了資料,不是正常的業務需求嗎,不知道如何處理^_^
我更改了套接字的超時設定,然而無卵用
除錯資訊
#sublime
#python3.8
#wenserver.py
('127.0.0.1', 51613)
('127.0.0.1', 51614)
('127.0.0.1', 51615)
('127.0.0.1', 51616)
('127.0.0.1', 51617)
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Program Files\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "D:\pythonIDE\files\multiprepare\async_webrequests\webserver.py", line 31, in threadsend
s.send("hello!!!".encode())
ConnectionResetError: [WinError 10054] 遠端主機強迫關閉了一個現有的連線。
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Program Files\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
Exception in thread File "D:\pythonIDE\files\multiprepare\async_webrequests\webserver.py", line 31, in threadsend
Thread-3:
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\threading.py", line 932, in _bootstrap_inner
s.send("hello!!!".encode())
ConnectionResetError: [WinError 10054] 遠端主機強迫關閉了一個現有的連線。
self.run()
File "C:\Program Files\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "D:\pythonIDE\files\multiprepare\async_webrequests\webserver.py", line 31, in threadsend
s.send("hello!!!".encode())
ConnectionResetError: [WinError 10054] 遠端主機強迫關閉了一個現有的連線。
Exception in thread Exception in thread Thread-5Thread-4:
:
Traceback (most recent call last):
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\threading.py", line 932, in _bootstrap_inner
File "C:\Program Files\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Program Files\Python38\lib\threading.py", line 870, in run
self.run()
File "C:\Program Files\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "D:\pythonIDE\files\multiprepare\async_webrequests\webserver.py", line 31, in threadsend
self._target(*self._args, **self._kwargs)
File "D:\pythonIDE\files\multiprepare\async_webrequests\webserver.py", line 31, in threadsend
s.send("hello!!!".encode())
ConnectionResetError: [WinError 10054] 遠端主機強迫關閉了一個現有的連線。
s.send("hello!!!".encode())
ConnectionResetError: [WinError 10054] 遠端主機強迫關閉了一個現有的連線。
[Cancelled]
#DOS命令板
#python3.8
#async_client.py
D:\pythonIDE\files\multiprepare\async_webrequests>python async_client.py
<socket.socket fd=492, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 51613), raddr=('127.0.0.1', 12346)>
第0個協程1609994242.2794733接收資料
<socket.socket fd=468, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 51614), raddr=('127.0.0.1', 12346)>
第1個協程1609994242.299716接收資料
<socket.socket fd=552, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 51615), raddr=('127.0.0.1', 12346)>
第2個協程1609994242.3198414接收資料
<socket.socket fd=592, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 51616), raddr=('127.0.0.1', 12346)>
第3個協程1609994242.3198414接收資料
<socket.socket fd=556, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 51617), raddr=('127.0.0.1', 12346)>
第4個協程1609994242.3391757接收資料
主程式執行完畢
D:\pythonIDE\files\multiprepare\async_webrequests>