在Python3中比较字符串和解码Unicode

1 投票
1 回答
592 浏览
提问于 2025-04-16 08:30

我正在做一些关于套接字和选择的编程,其中一个事件是通过接收到的字节字符串 'OK' 来触发的。我在服务器发送的所有内容上都使用了 utf_8 编码,并在客户端进行解码。然而,我的客户端比较没有正常工作,我的 if 语句从来没有评估为真。以下是相关的代码:

服务器端:

def broadcast_string(self, data, omit_sock): # broadcasts data utf_8 encoded to all socks
    for sock in self.descriptors:
        if sock is not self.server and sock is not omit_sock:
            sock.send(data.encode('utf_8'))
    print(data)

def start_game(self): # i call this to send 'OK'
    data = 'OK'
    self.broadcast_string(data, 0)
    self.new_round()

客户端:

else:   # got data from server
    if data.decode('utf_8') == 'OK': # i've tried substituting this with a var, no luck
        self.playstarted = True
    else:
        sys.stdout.write(data.decode('utf_8') + "\n")
        sys.stdout.flush()

    if self.playstarted is True: # never reached because if statement never True
        command = input("-->")

我看过 这个,我觉得我理解了,但显然并不是这样。我甚至在 Python 交互式环境中做过这些例子,并且得到了 True 的结果,但在运行这个程序时却没有。

谢谢!

1 个回答

1

TCP套接字没有消息边界。就像你最后提到的,你会收到多个消息合成一长串的情况。你需要自己把数据排好队,直到你有一条完整的消息,然后再把它当作一条完整的消息来处理。

每次select告诉你某个套接字有数据可以读取时,就把这些数据添加到一个读取缓冲区里,然后检查这个缓冲区里是否包含完整的消息。如果有,就从缓冲区的前面提取出这条消息并进行处理。一直这样做,直到找不到更多完整的消息为止,然后再调用select。另外,你只应该对完整的消息进行decode,因为如果不这样做,你可能会收到不完整的UTF-8多字节字符。

下面是一个简单的示例,使用\n作为消息结束符(没有错误处理):

tmp = sock.recv(1000)
readbuf += tmp
while b'\n' in readbuf:
    msg,readbuf = readbuf.split(b'\n',1)
    process(msg.decode('utf8'))

撰写回答