循环暂停时使用Python
我试图做多个while循环,但不知何故它们不起作用。我已经在互联网上搜索过了,但是我发现的问题都没有相同的问题 这是只包含必要信息的代码。我基本上是打开一个套接字,在第一步中提供输入(I\n)并接收输出。我想继续接收输出,直到输出中有一些特定字符xxx。然后我想转到下一个循环中的elif语句循环暂停时使用Python,python,loops,while-loop,Python,Loops,While Loop,我试图做多个while循环,但不知何故它们不起作用。我已经在互联网上搜索过了,但是我发现的问题都没有相同的问题 这是只包含必要信息的代码。我基本上是打开一个套接字,在第一步中提供输入(I\n)并接收输出。我想继续接收输出,直到输出中有一些特定字符xxx。然后我想转到下一个循环中的elif语句 def netcat(h, p): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((h,p)) i
def netcat(h, p):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((h,p))
i = 0
a = True
while a == True:
socket_list=[sys.stdin, s]
r,w,x = select.select(socket_list, [], [])
if i==0:
time.sleep(1)
message = s.recv(1024)
print(message)
s.send("i\n")
sys.stdout.flush()
while "xxx" not in message:
message = s.recv(1024)
print(message)
i+=1
elif i==1:
print("+++++++++++++++++++++++++++")
i+=1
print("hello")
server.close()
我希望代码能够反复打印if语句中的消息,然后打印hello,然后打印elif语句中的消息,然后打印hello,因为while循环仍然处于活动状态。总之,这是预期输出:
message
hello
+++++++++++++++++++++++++++
hello
hello
hello
hello...
它真正打印的是
message
hello
然后就结束了
我发现,如果我注释掉以下几行:
while "xxx" not in message:
message = s.recv(1024)
print(message)
它按预期工作。代码末尾的hello会一次又一次地打印到屏幕上。我只是不明白为什么这第二个while循环和它有关。我真的很感激你的帮助
由于工作代码是被请求的,这里也是完整的代码。主机名和端口来自仍在工作的CTF,因此您将与CTF服务器进行交互:
#!/usr/bin/env python
import socket
import time
import select
import sys
base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ ="
hostname = "18.188.70.152"
port = 36150
def netcat(h, p):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((h,p))
i = 0
a = True
b = True
while a == True:
socket_list=[sys.stdin, s]
r,w,x = select.select(socket_list, [], [])
if i==0:
time.sleep(1)
message = s.recv(1024)
print(message)
s.send("i\n")
sys.stdout.flush()
while "flag" not in message:
message = s.recv(1024)
print(message)
txtfile = message[9:38]
print(txtfile)
i+=1
elif i==1:
print("+++++++++++++++++++++++++++")
i+=1
print("hello")
server.close()
netcat(hostname, port)
我会检查你的缩进,试着在你的代码上安装并运行Autoep8,看看这是否能解决你的任何问题
[编辑]用户已更新了他们的问题,很明显这不是答案。您将基于事件的代码(
select.select()
)与阻塞同步代码(您的小,而与s.recv()循环
)混合在一起
如果希望代码不被阻塞,则每个recv()
都需要与前面的select()
配对
不仅如此,还必须检查select()
返回的值。只有s.recv()
如果s
在第一个返回的列表中。如果在任何其他情况下s.recv()
,该代码也会在接收呼叫时阻塞
更新:
尝试以下几点:
not_done = True
while not_done:
read_sockets, _, _ = select.select([sys.stdin, s], [], [])
if s in read_sockets:
message = s.recv(1024)
print(message)
... more code ...
if 'flag' in message:
... react on flag ...
if 'quit' in message:
not_done = False
... processing of other sockets or file descriptors ...
重要的一点是,在if分支中只有一个
s.recv()
,用于检查select是否检测到接收到的内容
外部while
将在稍后收到附加数据时返回到相同的if
分支
请注意,与套接字代码一起处理stdin是一件棘手的事情,可能还会在某个时候阻塞。您可能需要先将终端置于原始模式或其他模式,然后准备好自己处理部分行,也可能需要将输入回显给用户
更新:
如果您想在没有收到消息的情况下执行某项操作,可以给select()
一个超时,然后在套接字上没有收到任何消息的情况下执行其他处理。大概是这样的:
say_hello_from_now_on = False
not_done = True
while not_done:
read_sockets, _, _ = select.select([s], [], [], 1)
if s in read_sockets:
message = s.recv(1024)
print(message)
say_hello_from_now_on = True
elif say_hello_from_now_on:
print("hello")
另一个信息:当在终端中运行代码时,while循环似乎仍然处于打开状态,因为终端只在末尾显示空格,但不显示通常的行username@machine:文件夹(linux上)。请发布工作代码。您的代码有一些问题…而且,
server
代码的底部没有定义。嘿,谢谢您的快速回答。你能给我举个例子说明select如何与recv()结合吗?@Loeli我尝试一下我更新答案时使用的大纲。我现在根据你的建议尝试了一下,我将while循环更改为只包含一个recv,但仍然不起作用。如果我不需要stdin,我如何改进代码使其工作?很抱歉问了这么多问题,但我对此有点陌生。所以你想让它在没有收到任何消息时不断打印hello?您可以通过使用带有超时的select()
调用来实现这一点。如果read_sockets
不包含s
,只需打印hello
。或者你想让它只在收到第一条消息后才打印hello吗?@Loeli我还添加了使用select()
调用中的其他两个列表,我之前错过了这个调用,很抱歉。有了我的那个错误,代码就永远不会进入if
的recv
分支。