python--websocket資料解析

來源:互聯網
上載者:User

標籤:cep   cross   xtend   執行   格式化   websocket   pytho   sha1   nbsp   

# websocket實現原理‘‘‘1.服務端開啟socket,監聽ip和連接埠2.用戶端發送串連請求(帶上ip和連接埠)3.服務端允許串連4.用戶端產生一個隨機字串,和magic string組合進行一個sha1加密,加密。並將隨機字串發送給服務端5.然後服務端也要用相同的方式進行加密。6.然後服務端將加密之後的密串返回給用戶端7.用戶端將服務端返回的密串和自己加密之後的密串進行比對,如果一樣,說明遵循同樣的協議。如果不一樣,就沒法玩了·····‘‘‘import socketimport base64import hashlibfrom pprint import pprintdef get_headers(data):    """    將要求標頭格式化成字典    :param data:    :return:    """    header_dict = {}    data = str(data, encoding=‘utf-8‘)    header, body = data.split(‘\r\n\r\n‘, 1)    header_list = header.split(‘\r\n‘)    for i in range(0, len(header_list)):        if i == 0:            if len(header_list[i].split(‘ ‘)) == 3:                header_dict[‘method‘], header_dict[‘url‘], header_dict[‘protocol‘] = header_list[i].split(‘ ‘)        else:            k, v = header_list[i].split(‘:‘, 1)            header_dict[k] = v.strip()    return header_dictserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind((‘localhost‘, 8080))server.listen(5)# 等待使用者串連conn, addr = server.accept()# 握手訊息content = conn.recv(1024)‘‘‘>>> print(content)b‘GET / HTTP/1.1\r\nHost: localhost:8080\r\nConnection: Upgrade\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\nOrigin: http://localhost:63342\r\nSec-WebSocket-Version: 13\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: uuid=81a68694c772e0c62d4a5a3c256fe3e0; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2216453a8bf2bbe-09a40e8e58a866-5e442e19-1fa400-16453a8bf2c745%22%7D; Hm_lvt_2af69bc2b378fb58ae04ed2a04257ed1=1530411925; Pycharm-bdfc5fce=a920e49d-da4e-4d2f-a76e-17acfacc6462\r\nSec-WebSocket-Key: 1y6WpsSgfF80wqi3HpmrqQ==\r\nSec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n‘‘‘‘# 擷取要求標頭headers = get_headers(content)‘‘‘>>>pprint(headers){‘Cache-Control‘: ‘no-cache‘, ‘Connection‘: ‘Upgrade‘, ‘Cookie‘: ‘Pycharm-bdfc5fce=a920e49d-da4e-4d2f-a76e-17acfacc6462‘, ‘Host‘: ‘localhost:8080‘, ‘Origin‘: ‘http://localhost:63342‘, ‘Sec-WebSocket-Key‘: ‘RRGDeYeYSGEP9eHy85u8oQ==‘, ‘Sec-WebSocket-Version‘: ‘13‘, ‘Upgrade‘: ‘websocket‘, ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) ‘               ‘like Gecko‘, ‘method‘: ‘GET‘, ‘protocol‘: ‘HTTP/1.1‘, ‘url‘: ‘/‘}‘‘‘# 規定:魔法字串就叫這個magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"# 擷取隨機密串,並將其與魔法字串組合value = headers["Sec-WebSocket-Key"] + magic_string# 進行加密,規定,只能按照此加密方式hash_str = base64.b64encode(hashlib.sha1(bytes(value, encoding=‘utf-8‘)).digest())response_tpl = "HTTP/1.1 101 Switching Protocols\r\n"                "Upgrade:websocket\r\n"                "Connection: Upgrade\r\n"                "Sec-WebSocket-Accept: %s\r\n"                "WebSocket-Location: ws://%s%s\r\n\r\n"# 擷取握手訊息,組合魔法字串,進行sha1加密# 發送給用戶端response_str = response_tpl % (str(hash_str, encoding=‘utf-8‘), headers[‘Host‘], headers[‘url‘])conn.send(bytes(response_str, encoding=‘utf-8‘))# 也可以發送資料def send_msg(conn, msg_bytes):    """    WebSocket服務端向用戶端發送訊息    :param conn: 用戶端串連到伺服器端的socket對象,即: conn,address = socket.accept()    :param msg_bytes: 向用戶端發送的位元組    :return:    """    import struct    token = b"\x81"    length = len(msg_bytes)    if length < 126:        token += struct.pack("B", length)    elif length <= 0xFFFF:        token += struct.pack("!BH", 126, length)    else:        token += struct.pack("!BQ", 127, length)    msg = token + msg_bytes    conn.send(msg)    return True# 那麼便可以接受資料了,注意接受的資料必須按照一定的規則才能夠擷取while True:    info = conn.recv(1024)    payload_len = info[1] & 127    if payload_len == 126:        extend_payload_len = info[2:4]        mask = info[4:8]        decoded = info[8:]    elif payload_len == 127:        extend_payload_len = info[2:10]        mask = info[10:14]        decoded = info[14:]    else:        extend_payload_len = None        mask = info[2:6]        decoded = info[6:]    bytes_list = bytearray()    for i in range(len(decoded)):        chunk = decoded[i] ^ mask[i % 4]        bytes_list.append(chunk)    body = str(bytes_list, encoding=‘utf-8‘)    print(body)    # 可以將擷取的body加上新的字元    body = body + "我是你爸"    send_msg(conn, bytes(body, encoding="utf-8"))

  

  解包過程:(這個圖來自於武sir老師的部落格:https://www.cnblogs.com/wupeiqi/p/6558766.html)

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  |+ - - - - - - - - - - - - - - - +-------------------------------+|                               |Masking-key, if MASK set to 1  |+-------------------------------+-------------------------------+| Masking-key (continued)       |          Payload Data         |+-------------------------------- - - - - - - - - - - - - - - - +:                     Payload Data continued ...                :+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +|                     Payload Data continued ...                |+---------------------------------------------------------------+

  

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body>    <script>        ws = new WebSocket("ws://localhost:8080/");        //如果串連成功,會列印下面這句話,否則不會列印        ws.onopen = function () {            console.log(‘串連成功‘)        };        //接收資料,服務端有資料過來,會執行        ws.onmessage = function (event) {            console.log(event)        };        //服務端主動中斷連線,會執行.        //用戶端主動斷開的話,不執行        ws.onclose = function () {  }    </script></body></html>

  

  

  

 

 

python--websocket資料解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.