Python-сокеты, как выйти из бесконечного цикла и обработать исключения - PullRequest
1 голос
/ 20 января 2010

У меня есть скрипт, который подключается к удаленному серверу. Код ниже

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((remote_host,remote_port))
s.setblocking(False)


while True:
    try:
        data = s.recv(1024)

        if not data:
           break

        pkt_type = ord(data[2]) # get pkt type

        if pkt_type == Reset:
           s.send(data)

        if pkt_type == Authenticate:
           processAuthenticate(s,data)
           break

    except:
        pass

while(True)
 .
 .
 .

Я жду перезагрузки и возвращаюсь обратно на сервер, затем жду пакета Authenticate, несколько раз поворачиваю и возвращаю его на сервер. Как только это будет сделано успешно, теперь я могу запросить данные с сервера. Это делается в следующем цикле while (true).

Это лучший способ сделать это. Иногда, когда я запускаю скрипт, я получаю сообщение об ошибке, каков самый простой способ обработки исключения и предотвращения выполнения следующего цикла wile?

Спасибо

Ответы [ 3 ]

1 голос
/ 20 января 2010

Finite State Machine (FSM) - в значительной степени канонический способ сделать это. Хорошая справка для работы с FSM в Python: http://wiki.python.org/moin/FiniteStateMachine

0 голосов
/ 20 января 2010

В дополнение к вышеприведенным советам вам нужно буферизовать данные - при использовании потокового протокола вы не можете просто предполагать, что вы получите все нужные данные за один вызов recv. Вместо этого вы должны взять то, что вы прочитали из recv, и добавить его в буфер, а затем проверить буфер, чтобы увидеть, содержит ли он все данные для сообщения. Если это так, извлеките сообщение, обработайте его, затем повторите с остальной частью буфера. Если вы не можете извлечь дополнительные сообщения, вы возвращаетесь и читаете больше из сокета.

0 голосов
/ 20 января 2010

EDIT: Похоже, что FSM должно быть удобно здесь.

На самом деле, я предлагаю вам взглянуть на Twisted Reactor - я не использовал его сам (пока), но он выполняет всю основную работу и неприятные вещи, которые вам пришлось бы реализовать самостоятельно, если вы используете FSM и цикл обработки событий (который по сути является вашим while -циклом)

РЕДАКТИРОВАТЬ 2:

Несколько заметок (в ожидании вашего полного кода)

  1. тот факт, что у вас есть 2 последовательных while(true), ну, странно
  2. Вы, вероятно, хотите переместить оператор except: вверх, до оператора if not data и заменить pass на continue
  3. ord(data[2]) предполагает, что вы используете двоичный протокол, вам действительно следует рассмотреть возможность использования struct модулей unpack() и pack().
...