zoukankan      html  css  js  c++  java
  • websocket

    socket握手流程:
            服务端: 自己写服务端 或有些web框架写好了服务端
                step1 服务器开启socket 监听ip和端口
                step3 允许连接
                step5 服务端收到特殊值 对特殊值加密 用magic string='258EAFA5-E914-47DA-95CA-C5AB0DC85B11' 进行sha1加密  maginc string是固定值
                step6 将加密后的值发送给客户端
                            
            客户端: 浏览器(本质也是socket)
                step2 客户端链接服务器
                step4 握手 
                          客户端发一段特殊值给服务器 里面有一个客户端自己生成的随机字符串 同时客户端自己用magin string 进行sha1加密
                step7 客户端接收到加密的值  和自己的加密值比较 如果一样 说明是遵循了websocket协议 就可以进行收发数据 客户端和服务端都可以发数据
    View Code

     

    轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。
    优点:后端程序编写比较容易。
    缺点:请求中有大半是无用,浪费带宽和服务器资源。
    实例:适于小型应用。


    长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
    优点:在无消息的情况下不会频繁的请求,耗费资源小。
    缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。
    实例:WebQQ、Hi网页版、Facebook IM。
    长轮询意味着浏览器只需启动一个HTTP请求,其连接的服务器会“hold”住此次连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的Http请求,以此类推。

        轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。 
        优点:后端程序编写比较容易。 
        缺点:请求中有大半是无用,浪费带宽和服务器资源。 
        实例:适于小型应用。
    
    
        长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。 
        优点:在无消息的情况下不会频繁的请求,耗费资源小。 
        缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。 
        实例:WebQQ、Hi网页版、Facebook IM。
        长轮询意味着浏览器只需启动一个HTTP请求,其连接的服务器会“hold”住此次连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的Http请求,以此类推。
        
        
        WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket通讯协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准。 在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
    
        WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息
    
    
        http 
            单工通道 只能浏览器发起请求
            通过socket实现
            链接后断开
            短连接: 链接--响应--断开
            
        websocket是一条协议  用魔法字符串  magic string实现 本质是socket 
            双工通道  服务器也能主动给客户端发消息   本质是socket创建链接不断开
            特点 链接后不断开 你让他断开才断开
            
        socket握手流程:
            服务端: 自己写服务端 或有些web框架写好了服务端
                step1 服务器开启socket 监听ip和端口
                step3 允许连接
                step5 服务端收到特殊值 对特殊值加密 用magic string='258EAFA5-E914-47DA-95CA-C5AB0DC85B11' 进行sha1加密  maginc string是固定值
                step6 将加密后的值发送给客户端
                            
            客户端: 浏览器(本质也是socket)
                step2 客户端链接服务器
                step4 握手 
                          客户端发一段特殊值给服务器 里面有一个客户端自己生成的随机字符串 同时客户端自己用magin string 进行sha1加密
                step7 客户端接收到加密的值  和自己的加密值比较 如果一样 说明是遵循了websocket协议 就可以进行收发数据 客户端和服务端都可以发数据
            
    基于Python实现WebSocket握手过程
        客户端        
            ws = new WebSocket("ws://127.0.0.1:8002"); 会去连接服务端 并生成特殊字符串发过去 接收服务器返回的加密值 
            浏览器内置的类WebSocket
            如果连接成功  ws.onopen会自动执行
            
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>Title</title>
                </head>
                <body>
                    <script>
                        ws = new WebSocket("ws://127.0.0.1:8002");
                        ws.onopen = function () {
                            console.log(1111);
                            ws.send('hello村长')
                        };
                        ws.onmessage = function (event) {
                            console.log(event);
                        };
                        ws.onclose = function () {
                        }
    
                    </script>
                </body>
                </html>
    
        
        服务端s1.py
            import socket
            import base64
            import hashlib
    
            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
    
            def send_msg(conn, msg_bytes):
                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
    
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            sock.bind(('127.0.0.1', 8002))
            sock.listen(5)
    
            # 等待用户连接
            conn, address = sock.accept()
            # [握手消息]
            data = conn.recv(8096)
            headers = get_headers(data)
            # for k,v in headers.items():
            #     print(k,v)
            magic_string =  '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
            value = headers['Sec-WebSocket-Key'] + magic_string
            ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest()) #将随机字符串加上magic string后sha1加密
    
            response_tpl = "HTTP/1.1 101 Switching Protocols
    " 
                               "Upgrade:websocket
    " 
                               "Connection:Upgrade
    " 
                               "Sec-WebSocket-Accept:%s
    " 
                               "WebSocket-Location:ws://%s%s
    
    "
            # 获取[握手消息],magic string,sha1加密
            # 发送会客户端
            response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])
            conn.send(bytes(response_str, encoding='utf-8'))
    
            while True:
                info = conn.recv(8096)
                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')
    
                body = body + "aaaa"
                send_msg(conn,bytes(body,encoding='utf-8'))
    
    
    s15day114
    http 短连接:请求服务器响应后立马断开连接    
    
    
    轮询: 轮流询问要不要服务  一秒问n次 前后端压力大 占用带宽 浪费资源
     
    长轮旋: 连接不断开让服务器保存连接状态 直到收到消息返回了才断开
    
    长连接:用websocket封装  
        客户端 服务端 实时互动
        
        
    #WebSocket协议是基于TCP的一种新的协议。WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符。它实现了浏览器与服务器全双工(full-duplex)通信。其本质是保持TCP连接,在浏览器和服务端通过Socket进行通信。    
    '''    
    请求和响应的【握手】信息需要遵循规则:
        从请求【握手】信息中提取 Sec-WebSocket-Key
        利用magic_string 和 Sec-WebSocket-Key 进行hmac1加密,再进行base64加密 注:magic string为固定值:258EAFA5-E914-47DA-95CA-C5AB0DC85B11
        将加密结果响应给客户端
    '''    
        
    
    安装 gevent-websocket
        
        
        
            
            
            
        
    View Code

     

    socket握手流程:
    服务端: 自己写服务端 或有些web框架写好了服务端
    step1 服务器开启socket 监听ip和端口
    step3 允许连接
    step5 服务端收到特殊值 对特殊值加密 用magic string='258EAFA5-E914-47DA-95CA-C5AB0DC85B11' 进行sha1加密 maginc string是固定值
    step6 将加密后的值发送给客户端

    客户端: 浏览器(本质也是socket)
    step2 客户端链接服务器
    step4 握手
    客户端发一段特殊值给服务器 里面有一个客户端自己生成的随机字符串 同时客户端自己用magin string 进行sha1加密
    step7 客户端接收到加密的值 和自己的加密值比较 如果一样 说明是遵循了websocket协议 就可以进行收发数据 客户端和服务端都可以发数据

    socket握手流程:
            服务端: 自己写服务端 或有些web框架写好了服务端
                step1 服务器开启socket 监听ip和端口
                step3 允许连接
                step5 服务端收到特殊值 对特殊值加密 用magic string='258EAFA5-E914-47DA-95CA-C5AB0DC85B11' 进行sha1加密  maginc string是固定值
                step6 将加密后的值发送给客户端
                           
    socket握手流程:
    		服务端: 自己写服务端 或有些web框架写好了服务端
    			step1 服务器开启socket 监听ip和端口
    			step3 允许连接
    			step5 服务端收到特殊值 对特殊值加密 用magic string='258EAFA5-E914-47DA-95CA-C5AB0DC85B11' 进行sha1加密  maginc string是固定值
    			step6 将加密后的值发送给客户端
    						
    		客户端: 浏览器(本质也是socket)
    			step2 客户端链接服务器
    			step4 握手 
    					  客户端发一段特殊值给服务器 里面有一个客户端自己生成的随机字符串 同时客户端自己用magin string 进行sha1加密
    			step7 客户端接收到加密的值  和自己的加密值比较 如果一样 说明是遵循了websocket协议 就可以进行收发数据 客户端和服务端都可以发数据
    
    
    

      

    客户端: 浏览器(本质也是socket) step2 客户端链接服务器 step4 握手 客户端发一段特殊值给服务器 里面有一个客户端自己生成的随机字符串 同时客户端自己用magin string 进行sha1加密 step7 客户端接收到加密的值 和自己的加密值比较 如果一样 说明是遵循了websocket协议 就可以进行收发数据 客户端和服务端都可以发数据



    WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket通讯协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准。 在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

    WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息


    http
    单工通道 只能浏览器发起请求
    通过socket实现
    链接后断开
    短连接: 链接--响应--断开

    websocket是一条协议 用魔法字符串 magic string实现 本质是socket
    双工通道 服务器也能主动给客户端发消息 本质是socket创建链接不断开
    特点 链接后不断开 你让他断开才断开

    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')

    body = body + "aaaa"
    send_msg(conn,bytes(body,encoding='utf-8'))


    s15day114
    http 短连接:请求服务器响应后立马断开连接


    轮询: 轮流询问要不要服务 一秒问n次 前后端压力大 占用带宽 浪费资源

    长轮旋: 连接不断开让服务器保存连接状态 直到收到消息返回了才断开

    长连接:用websocket封装
    客户端 服务端 实时互动


    #WebSocket协议是基于TCP的一种新的协议。WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符。它实现了浏览器与服务器全双工(full-duplex)通信。其本质是保持TCP连接,在浏览器和服务端通过Socket进行通信。
    '''
    请求和响应的【握手】信息需要遵循规则:
    从请求【握手】信息中提取 Sec-WebSocket-Key
    利用magic_string 和 Sec-WebSocket-Key 进行hmac1加密,再进行base64加密 注:magic string为固定值:258EAFA5-E914-47DA-95CA-C5AB0DC85B11
    将加密结果响应给客户端
    '''

    安装 gevent-websocket






  • 相关阅读:
    数据结构 图的接口定义与实现分析(超详细注解)
    数据结构-优先队列 接口定义与实现分析
    什么是梯度?
    javascript当中火狐的firebug如何单步调试程序?
    给出一个javascript的Helloworld例子
    lvs dr 模型配置详解
    数据库连接池
    JDBC事务管理
    JDBC工具类:JDBCUtils
    详解JDBC对象
  • 原文地址:https://www.cnblogs.com/dingyunfeng/p/10518282.html
Copyright © 2011-2022 走看看