Цикл Python в то время как пауза - PullRequest
1 голос
/ 10 апреля 2019

Я пытаюсь сделать несколько циклов while, но почему-то они не работают.Я уже искал в Интернете, но ни одна из найденных проблем не имеет такой же проблемы.

Так вот код, содержащий только необходимую информацию.Я в основном открываю сокет, даю входные данные (i \ n) и получаю выходные данные на первом шаге.Я хочу продолжать получать вывод, пока в выводе не появятся какие-то конкретные символы ххх.Затем я хочу перейти к выражению 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, а затем печатать привет , затем сообщение из оператора elif и затем привет снова и снова, потому что цикл while все еще активен.Таким образом, в итоге это ожидаемый результат:

message
hello
+++++++++++++++++++++++++++
hello
hello
hello
hello...

То, что он действительно печатает, это

message
hello

, а затем он заканчивается.

Что я обнаружил, так это то, что еслиЯ закомментирую следующие строки:

                while "xxx" not in message:
                    message = s.recv(1024)
                    print(message)

работает как положено. привет в конце кода выводится на экран снова и снова.Я просто не понимаю, почему этот второй цикл 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 ]

2 голосов
/ 10 апреля 2019

Вы смешиваете код на основе событий (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(), который проверяет, было ли выбрано обнаруженное, что-то получено.

Внешний 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 голос
/ 10 апреля 2019

Я бы проверил ваши отступы, попробовал установить и запустить autopep8 в вашем коде и посмотреть, исправит ли это какие-либо ваши проблемы.

[edit] пользователь обновил свой вопрос, и ясно, что это не такответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...