У меня есть script, который подключается к удаленному серверу. Код ниже
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)
.
.
.
Я жду reset и возвращаюсь обратно к серверу, а затем дождаюсь пакета Authenticate, twiddle несколько бит и эхо, которое возвращается на сервер. Как только это будет выполнено, я могу теперь запрашивать данные с сервера. Это делается в следующем цикле while (true).
Это лучший способ сделать это. Иногда, когда я запускаю script, я получаю сообщение об ошибке, что является самым простым способом обработки исключения и предотвращения выполнения следующего цикла wile?
Спасибо
Конечный автомат (FSM) в значительной степени является каноническим способом делать подобные вещи. Хорошей ссылкой для выполнения FSM в Python является следующее: http://wiki.python.org/moin/FiniteStateMachine
В дополнение к приведенным выше советам вам необходимо буферизовать данные - при использовании протокола потока вы не можете просто предположить, что вы получите все данные, которые вы хотите, в один вызов recv. Вместо этого вы должны взять то, что вы прочитали из recv, и добавить его в буфер, а затем изучить буфер, чтобы узнать, содержит ли он все данные для сообщения. Если это так, извлеките сообщение, обработайте его, а затем повторите с остальной частью буфера. Когда вы не можете извлечь какие-либо дополнительные сообщения, вернитесь и прочитайте больше из сокета.
EDIT:
Похоже, FSM должен быть удобен здесь.
На самом деле, я предлагаю вам взглянуть на Twisted Reactor - не использовал его сам (пока), но он делает все объемную работу и неприятные вещи, которые вам нужно будет реализовать самостоятельно, если вы используете FSM и цикл событий (который, по сути, ваш while
-loop)
ИЗМЕНИТЬ 2:
Несколько заметок (в ожидании полного кода)
while(true)
, ну, нечетныйexcept:
вверх, перед оператором if not data
и заменить pass
на continue
ord(data[2])
предполагает, что вы используете двоичный протокол, вам действительно стоит использовать вместо этого struct
модули unpack()
и pack()
.