2012-06-09 5 views
4

Мне нужно получить сообщение буферов протокола на моем сервере python-torornado и получить материал из двоичного сообщения.Буферы протокола python - ошибка декодирования unicode

postContent = self.request.body 
message = prototemp.ReqMessage() 
message.ParseFromString(postContent) 

Он отлично работает с помощью испытательного инструмента. Когда я запустить его в песочнице среды и моделировать 1000 запросов от моего клиента, он работает в некоторых случаях, но в большинстве запросов, он бросает исключение -

File "server1.py", line 21, in post 
    message.ParseFromString(postContent) 
    File "/usr/lib/python2.6/site-packages/protobuf-2.4.1-py2.6.egg/google/protobuf/message.py", line 179, in ParseFromString 
    self.MergeFromString(serialized) 
    File "/usr/lib/python2.6/site-packages/protobuf-2.4.1-py2.6.egg/google/protobuf/internal/python_message.py", line 755, in MergeFromString 
    if self._InternalParse(serialized, 0, length) != length: 
    File "/usr/lib/python2.6/site-packages/protobuf-2.4.1-py2.6.egg/google/protobuf/internal/python_message.py", line 782, in InternalParse 
    pos = field_decoder(buffer, new_pos, end, self, field_dict) 
    File "/usr/lib/python2.6/site-packages/protobuf-2.4.1-py2.6.egg/google/protobuf/internal/decoder.py", line 544, in DecodeField 
    if value._InternalParse(buffer, pos, new_pos) != new_pos: 
    File "/usr/lib/python2.6/site-packages/protobuf-2.4.1-py2.6.egg/google/protobuf/internal/python_message.py", line 782, in InternalParse 
    pos = field_decoder(buffer, new_pos, end, self, field_dict) 
    File "/usr/lib/python2.6/site-packages/protobuf-2.4.1-py2.6.egg/google/protobuf/internal/decoder.py", line 410, in DecodeField 
    field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8') 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xce in position 1: invalid continuation byte 

В некоторых других случаях он дает эти ошибки -

UnicodeDecodeError: 'utf8' codec can't decode byte 0xbf in position 3: invalid start byte 

UnicodeDecodeError: 'utf8' codec can't decode byte 0xe7 in position 3: unexpected end of data 

В чем может быть причина?

+0

вы пытались с помощью Try/за исключением пункта, чтобы напечатать строку, которая генерирующий исключение? или использовать 'pdb', чтобы посмотреть, какие переменные находятся в этой точке? Потому что это говорит вам о проблеме: в строке указано какой-то символ, который не может быть закодирован с помощью utf-8. Таким образом, вам нужно обработать этот персонаж. (и если вы можете понять, что это такое и с этим вам придется справиться в целом, вы сможете справиться с этим) –

+0

Мое первое предположение заключается в том, что тестовый клиент использовал UTF-16, поскольку эти байты не похоже, соответствует UTF-8 или любому значащему западному набору карт –

+0

Похоже, что он получает сообщение, для которого ему не хватает определения протокола. Есть один или несколько излучателей, использующих другую спецификацию? – MarkHu

ответ

4

У меня была такая же проблема с RabbitMQ и протокольными буферами. Проблема заключается в том, что буфер протокола предполагает, что вход будет иметь тип str, тогда как RabbitMQ, по-видимому, декодирует сообщение как unicode в некоторых случаях (если массив байтов содержит байты больше 127). То же самое может произойти и с Торнадо. До сих пор кажется, что проблема может быть решена следующим фрагментом кода:

body = self.request.body 
if type(body) == unicode: 
    data = bytearray(body, "utf-8") 
    body = bytes(data) 
message = whatever.FromString(body) 

Этого код превращает юникод строку питона байт объекта, который может быть счастливо разобран буфером протокола сообщениями. Dunno, если есть какой-то лучший способ сделать это, но по крайней мере, похоже, это работает.

+0

+1 для вас. Благодаря! Ты спас меня от обострения. Можете ли вы рассказать мне, какие байты (данные) делают? Когда я нахожусь в интерактивном python, и я помогаю (байты), я не вижу никакой информации об этой функции. Благодаря! – Bitdiot

+0

Это не функция. Это тип python. –

+0

Если вы перейдете на python3, у вас не будет этих проблем. Просто говорю' –

Смежные вопросы