Чтение utf-8 байтов

Добрый ночи всем, столкнулся с тем, что при чтении utf-8 байтов он не хочет воспринимать русские символы нормально:
    def read_bytes(self, num):
        # python3 gives ordinal of byte directly
        bytes = self.rfile.read(num)
        if sys.version_info[0] < 3:
            return map(ord, bytes)
        else:
            return bytes
 
    def read_next_message(self):
 
        b1, b2 = self.read_bytes(2)
 
        fin    = b1 & FIN
        opcode = b1 & OPCODE
        masked = b2 & MASKED
        payload_length = b2 & PAYLOAD_LEN
 
        if not b1:
            print("Client closed connection.")
            self.keep_alive = 0
            return
        if opcode == CLOSE_CONN:
            print("Client asked to close connection.")
            self.keep_alive = 0
            return
        if not masked:
            print("Client must always be masked.")
            self.keep_alive = 0
            return
 
        if payload_length == 126:
            payload_length = struct.unpack(">H", self.rfile.read(2))[0]
        elif payload_length == 127:
            payload_length = struct.unpack(">Q", self.rfile.read(8))[0]
 
        masks = self.read_bytes(4)
        decoded = ""
        for char in self.read_bytes(payload_length):
            char ^= masks[len(decoded) % 4]
            decoded += chr(char)
        self.server._message_received_(self, decoded)
'''
+-+-+-+-+-------+-+-------------+-------------------------------+
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                     Payload Data continued ...                |
+---------------------------------------------------------------+
'''
 
FIN    = 0x80
OPCODE = 0x0f
MASKED = 0x80
PAYLOAD_LEN = 0x7f
PAYLOAD_LEN_EXT16 = 0x7e
PAYLOAD_LEN_EXT64 = 0x7f
 
OPCODE_TEXT = 0x01
CLOSE_CONN  = 0x8
В чём может быть проблема? Уже третий день думаю над это проблемой.
8 ответов

Что-то у вас странный инструментарий какой-то. Что есть self.rfile? Если бы вопрос был про стандартные питоновские инструменты - можно было бы ответить, а так - нет. В крайнем случае, str.decode (|encode) вам в помощь.


dondublon, rfile - из стандартной библиотеки:
if sys.version_info[0] < 3 :
    from SocketServer import ThreadingMixIn, TCPServer, StreamRequestHandler
else:
    from socketserver import ThreadingMixIn, TCPServer, StreamRequestHandler


А, понятно. Тогда пардон.


dondublon, а через данную функцию выдаётся такая ошибка:
def try_decode_UTF8(data):
    print('try_decode_utf8: 0 {0} 1 {1}'.format(data, data.decode('utf-8')))
    try:
        return data.decode('utf-8')
    except UnicodeDecodeError:
        return False
    except Exception as e:
        raise(e)
 return data.decode('utf-8')
AttributeError: 'str' object has no attribute 'decode'


В 3-м питоне у строки нет метода decode, только encode. По 3-му я не очень в курсе, сижу на 2-м.


dondublon, если использовать encode - получается b'sdasd\x01\...' русские символы в байтах. проблема заключается в тех 2 функциях, что я указал в начале.Провёл несколько тестов, если отправлять с клиента русские символы - они превращаются неизвестно во что: "Привет", а если на сервере делать уже русские символы и отправлять клиенту - все нормально.


А что значит "не хочет воспринимать"? Вы получили юникодную строку, что дальше, кто её не так отображает?


dondublon, я получаю не строку, а байты, байты обрабатываются теми функциями, что указаны в начале топика. В них видимо и проблема, поскольку они отказываются обрабатывать русские символы, а вернее криво их обрабатывают.