сравнивая строки и декодированный юникод в python3 - PullRequest
1 голос
/ 14 декабря 2010

Я занимаюсь программированием сокета / выбора, и одно из моих событий запускается входящей строкой байтов '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("-->")

Я прочитал это , и я думаю, что следую этому, но, очевидно, нет. Я даже делал примеры, используя оболочку python, и заставил их оценить True, но не при запуске этой программы.

Спасибо!

1 Ответ

1 голос
/ 14 декабря 2010

Сокеты 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'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...