在python3中比较字符串和解码的unicode

时间:2010-12-14 03:55:28

标签: python sockets select encoding

我正在进行一些套接字/选择编程,我的一个事件由传入的'OK'字节字符串触发。我正在使用utf_8来编码从服务器发送的所有内容并在客户端上对其进行解码。但是,我的客户端比较不起作用,我的if语句永远不会评估为true。以下是有问题的代码:

服务器端:

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("-->")

我读过this,我想我正在关注它,但显然不是。我甚至使用python shell完成了这些示例,并将它们计算为True,但是当我运行此程序时却没有。

谢谢!

1 个答案:

答案 0 :(得分: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'))