2013-05-11 4 views
0

Я работаю над созданием сервера websocket через python (я новичок в python), и я добился значительного прогресса, но я не могу отправлять данные в веб-браузер. Я могу установить соединение и получить данные из браузера, но я не могу отправить обратно данные. Браузер просто игнорирует его. Я бы предположил, что если браузер получил пакет, который не соответствовал спецификациям, он прекратил бы соединение, но соединение останется активным.Websocket: Browser dosn't, похоже, не получает данные с сервера python

Вот метод я использую для кодирования данных в кадре:

def encode_message(data): 
    frame = "\x81" 
    size = len(data) 
    if size * 8 <= 125: 
     frame += chr(size) 
    else: 
     raise Exception("Uh, oh. Strings larger than 125 bits are not supported") 

    return frame + data 

Я посылаю данные, используя sock.sendall(framed_data). В чем может быть проблема? Данные для сообщения типа «yo» заканчиваются 10000001 00000010 01111001 01101111 (пробелы добавлены для лучшей читаемости). Почему браузер не принимает такое сообщение? Не соответствует ли это рекомендациям, изложенным в the specification? Я пытаюсь поддержать самую последнюю версию websocket, которая, я считаю, является версией 13. Я использую python версии 2.7.3.

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

Вот код, который вызывает функцию выше:

def send(data): 
    frame = encode_message(data) 
    print "Sending all..." 
    sock.sendall(frame) #Socket that handles all communications with client 
    print "Frame sent :)" 
    return 

я скачал Wireshark нюхать пакеты, пересылаемые между сервером и розеткой. Пакеты, отправленные моим сервером, идентичны пакетам, отправленным с сервера, который принят браузером. Я не видел никакой разницы. (Я посмотрел непосредственно на источник hex)

+0

Так что никто не знает, как это исправить? – CoderOfHonor

+0

Какие обратные вызовы запускаются в вашем браузере? Выполняется ли 'onopen' в конце вашего рукопожатия? Запускаете ли 'onerror' или' onclose' позже? Помните ли вы, что связь открыта после завершения вашего рукопожатия? Если ни один из этих вопросов не поможет вам ответить, можете ли вы опубликовать свой полный серверный источник плюс некоторый простой клиентский код, демонстрирующий проблему? – simonc

+0

'onopen' запускается в конце моего рукопожатия. 'onclose' не запускается до тех пор, пока веб-узел не будет отключен сервером. 'onerror' никогда не вызывается, потому что не возникает ошибка. После установления рукопожатия сервер может получать сообщения от клиента, но обратное не работает. – CoderOfHonor

ответ

0

Я, наконец, выяснил проблему! Потребовалось много времени на отладку и беспорядок от моего кода. После тщательного изучения пакетов, отправленных туда и обратно между сервером и клиентом, я наконец понял, что возникла проблема с ответом на обновление соединения моего сервера. Всякий раз, когда он вычислял хэш, он также добавлял \n до конца. Это привело к \n\r\n в конце одной из строк. Клиент интерпретировал это как конец этой передачи и все, что следовало, анализировали с использованием протокола WebSocket. После этого у меня была другая строка в заголовке, поэтому она полностью испортила мои сообщения с клиентом. Я все еще мог читать от клиента, но если бы я попытался написать клиенту, данные перепутались бы.

1

Второй байт вашего переданного сообщения (и проверка длины вашего кода) выглядит неправильно. Длина сообщения находится в байт, а не бит.

От RFC6455 §5.2 (курсив мой)

Длина полезной нагрузки: 7 бит, 7 + 16 бит, или 7 + 64 бита

Длина "Payload данных", в байт: если 0-125, то есть длина полезной нагрузки .

Причина, по которой в браузере ничего не получено, заключается в том, что ваше сообщение утверждает, что у него есть 16-байтовый корпус. Браузер будет читать два дополнительных байта, которые вы отправляете, затем блок ожидает еще 14 байтов, которые он ожидает, но вы не отправляете.

Если вы измените второй байт на количество байтов в сообщении - двоичный код 0x2 или 00000010, тогда все должно работать.

+0

Я попробовал ваше предложение, спасибо, что поймал это, но я все еще не мог заставить браузер получать сообщение ... – CoderOfHonor

+0

Daft вопрос, но вы отправляете 4 байта, я его принимаю? (Вместо бинарной версии сообщения, которое вы отправили в виде строки с 32 символами). Было бы интересно увидеть, что код, который вызывает 'encode_message', затем отправляет данные в рамке. – simonc

+0

Я добавил код, который вызывает функцию выше. Фактическая строка, которую я отправляю, выглядит так: ' Ok'. – CoderOfHonor

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