Python while循环暂停

时间:2019-04-10 04:50:25

标签: python loops while-loop

我正在尝试执行多个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)



2 个答案:

答案 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]用户已更新了他们的问题,很明显,这不是答案。