Python 一次做更多的迭代
我有一个阻塞for循环,我试图用套接字连接到服务器。 我想做一个非阻塞循环,因为它需要很多时间,比如重叠连接。Python 一次做更多的迭代,python,for-loop,Python,For Loop,我有一个阻塞for循环,我试图用套接字连接到服务器。 我想做一个非阻塞循环,因为它需要很多时间,比如重叠连接。 下面是我的示例代码: import socket for _ in range(100): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsocko
下面是我的示例代码:
import socket
for _ in range(100):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.connect(('', 4444))
正如MLAlex所建议的,使用asyncio库是有意义的 这是从以下方面得到启发的: e、 g.与此回送服务器连接(回送一条消息需要三秒): 产生:
Send: 'msg 0'
Send: 'msg 1'
Send: 'msg 2'
Send: 'msg 3'
Send: 'msg 4'
Send: 'msg 5'
Send: 'msg 6'
Send: 'msg 7'
Send: 'msg 8'
Send: 'msg 9'
Received: 'msg 0'
Close the connection
Received: 'msg 1'
Close the connection
Received: 'msg 2'
Close the connection
Received: 'msg 3'
Close the connection
Received: 'msg 4'
Close the connection
Received: 'msg 5'
Close the connection
Received: 'msg 6'
Close the connection
Received: 'msg 7'
Close the connection
Received: 'msg 8'
Close the connection
Received: 'msg 9'
Close the connection
['msg 0', 'msg 1', 'msg 2', 'msg 3', 'msg 4', 'msg 5', 'msg 6', 'msg 7', 'msg 8', 'msg 9']
在三秒左右,即仅满足一个请求所需的时间
real 0m3,169s
user 0m0,044s
sys 0m0,084s
如果我们在服务器回复所需的时间上引入一些差异,我们可以看到客户端接收结果的顺序不正确。
e、 g.第10行:
await asyncio.sleep(randint(3,4))
然后,客户端的输出变为:
(tih1) SO $ time python aio_cnx.py
Send: 'msg 0'
Send: 'msg 1'
Send: 'msg 2'
Send: 'msg 3'
Send: 'msg 4'
Send: 'msg 5'
Send: 'msg 6'
Send: 'msg 7'
Send: 'msg 8'
Send: 'msg 9'
Received: 'msg 1'
Close the connection
Received: 'msg 2'
Close the connection
Received: 'msg 3'
Close the connection
Received: 'msg 7'
Close the connection
Received: 'msg 8'
Close the connection
Received: 'msg 9'
Close the connection
Received: 'msg 0'
Close the connection
Received: 'msg 4'
Close the connection
Received: 'msg 5'
Close the connection
Received: 'msg 6'
Close the connection
['msg 0', 'msg 1', 'msg 2', 'msg 3', 'msg 4', 'msg 5', 'msg 6', 'msg 7', 'msg 8', 'msg 9']
real 0m4,135s
user 0m0,059s
sys 0m0,013s
基于您尝试在套接字上执行非块I/O的事实,尝试使用选择器 我的示例代码用于在本地主机ssh服务器上运行 有10次并发连接尝试
import sys
import socket
import selectors
sel = selectors.EpollSelector()
def read_conn(obj, mask):
try:
data = obj.recv(1024)
if data :
print(data.decode("utf-8"))
else:
sel.unregister(obj)
obj.close()
except Exception as ex:
print( ex )
sel.unregister(obj)
obj.close()
def write_conn(obj, mask):
msg=b"flooding\n\n"
obj.send(msg)
sel.unregister(obj)
sel.register(obj,selectors.EVENT_READ,read_conn)
return
for i in range(10) :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ('127.0.0.1',22)
try:
sock.connect(addr)
print(f"tried {i}")
sock.setblocking(False)
sel.register(sock,selectors.EVENT_WRITE, write_conn)
except socket.error as ex:
print("fail to connect error {}".format(ex))
sys.exit(1)
while True:
events = sel.select(1)
if len(events) == 0:
print("all done")
break
for key, mask in events:
callback= key.data
callback(key.fileobj,mask)
在我的虚拟机上显示它的输出
tried 0
tried 1
tried 2
tried 3
tried 4
tried 5
tried 6
tried 7
tried 8
tried 9
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
[Errno 104] Connection reset by peer
[Errno 104] Connection reset by peer
[Errno 104] Connection reset by peer
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
cut out duplicate outputs
all done
你要找的是多线程。看看异步IO的I/O操作如果你在浏览器中搜索“Python多处理”,你会找到比我们在这里管理的更好的参考资料。我知道线程、多处理和异步IO,但如果可以的话,我需要一个代码示例。谢谢你,阿加尼真的很感谢你的评论和代码,但我的代码比我在问题中给出的示例更复杂,你的代码永远不会与我的代码一起工作。对不起,我明白了。没问题,根据提供的信息,这是一种方法。如果它不符合您的限制,它可能会帮助其他人作为答案是的,这是因为我不想使我的代码繁重或完全打乱它。很抱歉,againi在socket.connect()之后进行了非块设置,因为connect()在非块模式下很容易引发异常,错误号115如果要进行非块连接,请将sock.connect()调用替换为sock.connect_ex()并将sock.setblocking()移到sock.connect_ex()之前,另请参见
import sys
import socket
import selectors
sel = selectors.EpollSelector()
def read_conn(obj, mask):
try:
data = obj.recv(1024)
if data :
print(data.decode("utf-8"))
else:
sel.unregister(obj)
obj.close()
except Exception as ex:
print( ex )
sel.unregister(obj)
obj.close()
def write_conn(obj, mask):
msg=b"flooding\n\n"
obj.send(msg)
sel.unregister(obj)
sel.register(obj,selectors.EVENT_READ,read_conn)
return
for i in range(10) :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ('127.0.0.1',22)
try:
sock.connect(addr)
print(f"tried {i}")
sock.setblocking(False)
sel.register(sock,selectors.EVENT_WRITE, write_conn)
except socket.error as ex:
print("fail to connect error {}".format(ex))
sys.exit(1)
while True:
events = sel.select(1)
if len(events) == 0:
print("all done")
break
for key, mask in events:
callback= key.data
callback(key.fileobj,mask)
tried 0
tried 1
tried 2
tried 3
tried 4
tried 5
tried 6
tried 7
tried 8
tried 9
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
[Errno 104] Connection reset by peer
[Errno 104] Connection reset by peer
[Errno 104] Connection reset by peer
SSH-2.0-OpenSSH_7.4
Protocol mismatch.
cut out duplicate outputs
all done