python实现websocket

摘要:
1) header_List=标头。split(“”)foriinrange(0,header_dict['method']:header_dict['url'],header_direct['protocol']=header_list[i]。split('')else,addr=服务器。accept())#握手消息内容=conn.rcv(8096)“”&gt,
# websocket实现原理
'''
1.服务端开启socket,监听ip和端口
2.客户端发送连接请求(带上ip和端口)
3.服务端允许连接
4.客户端生成一个随机字符串,和magic string组合进行一个sha1加密,加密。并将随机字符串发送给服务端
5.然后服务端也要用相同的方式进行加密。
6.然后服务端将加密之后的密串返回给客户端
7.客户端将服务端返回的密串和自己加密之后的密串进行比对,如果一样,说明遵循同样的协议。如果不一样,就没法玩了·····
'''

import socket
import base64
import hashlib
from pprint import pprint


def get_headers(data):
    """
    将请求头格式化成字典
    :param data:
    :return:
    """
    header_dict = {}
    data = str(data, encoding='utf-8')

    header, body = data.split('

', 1)
    header_list = header.split('
')
    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_dict


server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 8080))
server.listen(5)

# 等待用户连接
conn, addr = server.accept()

# 握手消息
content = conn.recv(8096)
'''
>>> print(content)

b'GET / HTTP/1.1
Host: localhost:8080
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:63342
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: 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
Sec-WebSocket-Key: 1y6WpsSgfF80wqi3HpmrqQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

'
'''

# 获取请求头
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
" 
               "Upgrade:websocket
" 
               "Connection: Upgrade
" 
               "Sec-WebSocket-Accept: %s
" 
               "WebSocket-Location: ws://%s%s

"

# 获取握手消息,组合魔法字符串,进行sha1加密
# 发送给客户端
response_str = response_tpl % (str(hash_str, encoding='utf-8'), headers['Host'], headers['url'])
conn.send(bytes(response_str, encoding='utf-8'))

  

<!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('连接成功')
        }
    </script>
</body>
</html>

  python实现websocket第1张

免责声明:文章转载自《python实现websocket》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇centos7 安装图行界面及卸载谷歌浏览器之software_reporter_tool.exe禁用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

HBase shell 简单使用

引言HBase提供了丰富的访问接口。  • HBase Shell  • Java clietn API  • Jython、Groovy DSL、Scala  • REST  • Thrift(Ruby、Python、Perl、C++…)  • MapReduce  • Hive/Pig其中HBase Shell是常用的便捷方式 首先你需要一个HBase...

用Socket开发的一枚小型实时通信App

Socket 英文原意是插座。 在网络世界里, 当一台主机温柔而体贴的同时提供多个服务时, 每个服务被绑定在一个端口上, 而每个端口就好像一个小插座。 用户们连接对应的插座去获取相应的服务。 在Node.js中,使用的是socket.io来实现Realtime的通信。 当程序两端实现数据通信时, 每一端便化身为一枚可爱的Socket了。 本示例使用Expr...

如何用delphi读取网卡物理号

unit Main; interface uses   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,   Forms, Dialogs, StdCtrls,   Nb, ExtCtrls; type   TForm1 = class(TForm)     Panel...

HTML基本语法

1.1 什么是HTML HTML是用来制作网页的标记语言 HTML是Hypertext Markup Language的英文缩写,即超文本标记语言 HTML语言是一种标记语言,不需要编译,直接由浏览器执行 HTML文件是一个文本文件,包含了一些HTML元素,标签等 HTML文件必须使用.html或.htm为文件名后缀 HTML是大小写不敏感的,HTML...

FusionCharts属性大全

属性的分类就以官方的API文档为准吧: 1.Chart: <1>Functional Attributes(功能属性) <2>Titles and AxisNames(标题和坐标抽名字) <3> Charts Cosmetics(图表美容属性) <4>Divisional Lines/Grids(...

【HDOJ】3686 Traffic Real Time Query System

这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图。转化为lca求解。结合点——双连通分量与LCA。 1 /* 3686 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string...