2012-03-09 2 views
0

Мне грозила задача реализовать простые серверные дескрипторы для Python с поддержкой websocket. Конечно, я знаю о торнадоио, но проблема заключается в его реализации. Шаг соединений и рукопожатия (обмен частными ключами), я сделал, но тогда у меня проблемы. 1) Появляется сообщение от клиента (браузера), но они закодированы. Я нашел информацию об этом, но не мог понять, как их декодировать. Документация гласит, что сообщение скрыто под маской (как я понимаю, это XOR), но ключ к открытию этой маски игнорируется клиентом (браузером) или я ее не вижу. 2) сообщения, которые отправляют сервер, клиент (браузер) игнорируются. Отправка в соответствии с документациейwebsocket server на python.problems

conn.send(bytes(0x00)) 
conn.send(u'test'.encode('utf-8')) 
conn.send(bytes(0xFF)) 

загрузил исходный код here и я отправляю источник здесь

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 
import socket,sys,hashlib,time 
from base64 import b64encode 
from threading import Thread 
#=================================== 
bindto=['127.3.1.4',80] 
thr_kill=False 

def getsett(text,ss,si,es): 
#this function i'm use for cut strings by known patterns 
    global getsett_i1,getsett_i2 
    if text==None: return None 
    if ss==None: return None 
    if es==None: return None 
    text1=text.lower() 
    ss=ss.lower() 
    es=es.lower() 
    if ss!='': getsett_i1=text1.find(ss,si) 
    else: getsett_i1=si 
    if getsett_i1==-1: return None 
    if es!='': getsett_i2=text1.find(es,getsett_i1+len(ss)) 
    else: getsett_i2=len(text1) 
    if getsett_i2==-1: return None 
    return text[getsett_i1+len(ss):getsett_i2] 

def thr_waitclient(): 
    global bindto,thr_kill 
    serv=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
    serv.bind((bindto[0],bindto[1])) 
    while thr_kill==False: 
     serv.listen(1) 
     conn,adr=serv.accept() 
     data=conn.recv(4096) 
     print data 
#checking connection type 
     if getsett(data,'connection: ',0,"\r\n").lower()=='upgrade' and getsett(data,'upgrade: ',0,"\r\n").lower()=='websocket': 
#handshake 
     wbs=getsett(data,'Sec-WebSocket-Key: ',0,"\r\n") 
     conn.send("HTTP/1.1 101 Web Socket Protocol Handshake\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+b64encode(hashlib.sha1(wbs+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest())+"\r\nSec-WebSocket-Origin: *\r\nAccess-Control-Allow-Origin: *\r\nOrigin: *\r\nAccess-Control-Allow-Credentials:true\r\nAccess-Control-Allow-Headers:content-type\r\n\r\n") 
#wait for clien's messahe,then send response 
     while True: 
      print conn.recv(4096) #first problem:message is coded 
      conn.send(bytes(0x00)) 
      conn.send(u'test'.encode('utf-8')) 
      conn.send(bytes(0xFF)) 
      #second problem: client ignore message 
      time.sleep(0.5) 
     else: 
     conn.close() 
    serv.close() 

Thread(None,thr_waitclient).start() 
while thr_kill!=True: 
    time.sleep(0.3) 
sys.exit(0) 
+0

Вы смотрели на существующих реализаций, таких как автобан, ws4py, txws? – jfs

ответ

2

Существуют два различных основных варианта протокола WebSocket. Ваш примерный код - это смешение, которое не будет работать ни для одного протокола.

Последние версии Chrome, Firefox и IE10 используют новый протокол HyBi/IETF. Старые версии Chrome и текущие версии Safari (настольные и мобильные) используют старый протокол Hixie.

В протоколе Hixie используется «\ x00», чтобы указать начало кадра и «\ xff», чтобы указать конец кадра. Протокол Hixie не маскировал данные браузера для сервера. Существуют две основные версии протокола Hixie: 75 и 76. В версии 76 имеется дополнительная часть данных, которая заменяется сразу после заголовков, но до обычных кадров.

В более позднем протоколе HyBi/IETF используется заголовок длиной 2-10 байт, который содержит длину полезной нагрузки и отдельный конечный маркер. В новом протоколе данные полезной нагрузки от браузера к серверу маскируются с использованием 4-байтовой рабочей маски XOR. Первые 4 байта после заголовка - это маска в браузере для случая сервера. Данные сервера для браузера не маскируются. Заголовки и процесс рукопожатия также отличаются для протокола HyBi.

Многие серверы WebSocket поддерживают как версии Hixie, так и HyBi/IETF протокола WebSocket (вы можете определить из заголовков, отправленных браузером, какую версию он использует).

Вот спецификации для различных версий протокола:

+0

Thx ** kanaka **! – GenryRar

+0

Я действительно ошибаюсь с версиями протокола. я использую правильное рукопожатие и неправильную отправку и получение)) может ли кто-нибудь помочь мне с этим? Я говорю об алгоритме разоблачения и алгоритме правильной отправки daa клиенту. боюсь, у меня недостаточно знаний для этого :( – GenryRar

+0

Thx again ** kanaka **, я перечитал документацию, и теперь все работает нормально! – GenryRar

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