我正在尝试执行多个while循环,但是以某种方式它们不起作用。我已经在互联网上搜索了,但是发现的所有问题都没有。
这是仅包含必要信息的代码。我基本上是打开一个套接字,输入in(i \ n)并在第一步中接收输出。我要继续接收输出,直到在输出中包含一些特定字符xxx为止。然后,我想在下一个循环中转到elif语句。
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)
答案 0 :(得分:2)
您正在将基于事件的代码(select.select()
)与阻塞的同步代码(您的小型while
循环与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")
答案 1 :(得分:1)
我会检查您的缩进,尝试在代码上安装并运行autopep8,看看是否能解决您的任何问题。
[edit]用户已更新了他们的问题,很明显,这不是答案。