Python套接字,如何跳出无限循环并处理异常

1 投票
3 回答
1207 浏览
提问于 2025-04-15 18:14

我有一个脚本,它可以连接到一个远程服务器。下面是代码

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)
 .
 .
 .

我会等待重置,然后把信息回传给服务器,接着再等一个认证的数据包,稍微处理一下数据,再把它回传给服务器。一旦这些步骤成功完成,我就可以请求服务器上的数据了。这是在接下来的 while(true) 循环中完成的。

这样做是最好的方法吗?有时候我运行这个脚本时会遇到错误,处理这些错误的最简单方法是什么?我该怎么做才能防止下一个 while 循环继续执行?

谢谢

3 个回答

0

编辑: 看起来这里应该用状态机会比较方便。

其实,我建议你看看 Twisted Reactor - 我自己还没用过,但它可以处理很多繁琐的工作和复杂的事情,如果你用状态机和事件循环(你的 while 循环基本上就是这个意思),你就得自己实现这些。

编辑 2:

在等你完整代码的时候,有几点要注意:

  1. 你有两个连续的 while(true),这有点奇怪。
  2. 你可能想把 except: 语句往上移动,放在 if not data 语句之前,并把 pass 替换成 continue
  3. ord(data[2]) 表明你在使用二进制协议,你真的应该考虑用 struct 模块的 unpack()pack()
0

除了上面提到的建议,你还需要使用缓冲区来处理数据。因为在使用流协议的时候,你不能指望一次调用recv就能得到你想要的所有数据。相反,你需要把从recv读取到的数据放到一个缓冲区里,然后检查这个缓冲区,看看里面是否已经包含了完整的消息。如果有,就提取出这条消息,处理它,然后再继续处理缓冲区里的其他数据。当你无法再提取出更多的消息时,就回去从套接字中读取更多的数据。

1

有限状态机(FSM)基本上是处理这类问题的标准方法。想要在Python中使用有限状态机,可以参考这个链接: http://wiki.python.org/moin/FiniteStateMachine

撰写回答