在Python3中比较字符串和解码Unicode
我正在做一些关于套接字和选择的编程,其中一个事件是通过接收到的字节字符串 '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'))