python socket websocket 三次握手 详解

2018-05-31  本文已影响0人  wangtieshan

自己研究 socket

然后按照度娘上和官方文档的那样起了一个服务

然后用 Python 写了一个客户端,然后可以连接成功

但是当我在 websocket 上连接时

总是服务器断开连接

然后就开始填坑

。。。

最后总结:

Python 客户端连接 python 服务端不需要处理三次握手

而 websocket 连接时需要处理三次握手

汗颜

第一次收到请求时,是需要处理三次握手的

下面代码都是有详细注释的

 data = self.connection.recv(1024)

print 'first get data %s ' % data

headers = self.parse_headers(data)

token = self.generate_token(headers['Sec-WebSocket-Key'])

        self.connection.send('\
HTTP/1.1 101 WebSocket Protocol Hybi-10\r\n\
Upgrade: WebSocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Accept: %s\r\n\r\n' % token)



######## 辅助方法

def parse_data(self, msg):

        if len(msg) == 0:
            return  ''

        # 去除二进制中的第1位
        v = ord(msg[1]) & 0x7f

        # p 掩码的开始位

        # 1位如果是 126 表接下来的两个字节才是长度
        # 接下来两个是长度,加上0位和1位,就是 4 位开始掩码
        if v == 0x7e:
            p = 4

        # 1位 127 表接下来的八个字节才是长度
        # 接下来 8 个代表长度,加上 0 and 1 则是 10 开始掩码
        elif v == 0x7f:
            p = 10

        # 1 位 1-125 则本身代表长度
        # 0 and 1 则 2 开始掩码
        else:
            p = 2

        # mark 掩码为包长之后的 4 个字节
        mask = msg[p:p + 4]
        data = msg[p + 4:]

        #print 'mask num is \n %s' % [ord(v) for v in mask]

        #print 'mask little num is \n %s' % [ord(v) & 0x7f for v in mask]

        #print 'mask is \n %s' % [chr(ord(v) & 0x7f) for v in mask]

        ori = ''.join([chr(ord(v) ^ ord(mask[k % 4])) for k, v in enumerate(data)])

        print 'origin data is \n %s' % ori

        return ori

    def parse_headers(self, msg):
        headers = {}
        header, data = msg.split('\r\n\r\n', 1)
        for line in header.split('\r\n')[1:]:
            key, value = line.split(': ', 1)
            headers[key] = value
        headers['data'] = data
        return headers

    def generate_token(self, msg):
        key = msg + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
        ser_key = hashlib.sha1(key).digest()
        return base64.b64encode(ser_key)

经过上面的处理就可以正常的发送和接收数据了

        while True:

                data = self.connection.recv(1024)
上一篇下一篇

猜你喜欢

热点阅读