1. 程式人生 > 其它 >python的asyncio庫,事件迴圈,直接使用socket物件

python的asyncio庫,事件迴圈,直接使用socket物件

技術標籤:eventlooppythonsocket

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>