Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
循环暂停时使用Python_Python_Loops_While Loop - Fatal编程技术网

循环暂停时使用Python

循环暂停时使用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

我试图做多个while循环,但不知何故它们不起作用。我已经在互联网上搜索过了,但是我发现的问题都没有相同的问题

这是只包含必要信息的代码。我基本上是打开一个套接字,在第一步中提供输入(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)




我会检查你的缩进,试着在你的代码上安装并运行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
分支。