2012-03-09 97 views
0

我面臨的任務是爲websocket提供支持,爲Python實現一個簡單的服務器句柄。當然我知道關於tornadoIO,但問題在於實現它。 連接和握手(交換私鑰)的步驟,我做了,但後來我有問題。 1)來自客戶端(瀏覽器)的消息確實出現,但它們被編碼。我找到了關於它的信息,但無法弄清楚如何解碼它們。文檔說消息隱藏在掩碼下面(據我所知它是一個XOR),但是打開這個掩碼的鑰匙沒有被客戶端(瀏覽器)拒絕,或者我沒有看到它。 2)發送服務器的消息,客戶端(瀏覽器)被忽略。根據文檔python.problems上的websocket服務器

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 2012-03-10 00:02:56

回答

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服務器都支持WebSocket協議的Hixie和HyBi/IETF版本(您可以從瀏覽器發送的頭文件中確定它使用的是什麼版本)。

下面是各種協議版本規格:

+0

Thx ** kanaka **! – GenryRar 2012-03-10 10:04:15

+0

我真的與版本的協議錯誤。我使用正確的握手和錯誤的發送和接收))任何人都可以幫助我嗎?我說的算法揭露和算法正確發送DAA到客戶端。恐怕我沒有足夠的知識:( – GenryRar 2012-03-10 10:11:48

+0

Thx again ** kanaka **,我重讀文檔,現在一切正常! – GenryRar 2012-03-10 11:21:37