zoukankan      html  css  js  c++  java
  • websocket如何解决tcp多请求自动合并成一条请求的问题

        这几天又遇到了个头大的问题 —— tcp会将几个连续发送出去的请求合并成一个请求发出去,也就是说,并不是在客户端send几次,server端就接收几次,有可能客户端连续改送5个请求,但在server端5个请求却是合并成一个,只recv一次的。

        如果是普通的socket编程,拆解几次请求应该还比较好做,因为改送和接收的消息都是明文,自己给发送的数据加个特殊的结束符就好了,接收时,根据结束符split一下,就可以将多个请求拆解开了。但websocket发送和接收的并不是明文,还会特别加上一些东西。而当下safari支持还是76协议,chrome已经在支持draft10了,拆解又需要分两种情况分别对待了。

       76协议还好办,因为加的字符很简单,所有的消息都会在前面加\x00,后面加\xff。所以拆解也比较容易,但draft-10就很麻烦了。

    封装了一下相关的代码:

        def __parseRequire(self,data):

            dataList = []

            if self.__getDraftType() == "76":

                dataList = data[1:-1].split("\xFF\x00")

            elif self.__getDraftType() == "10":

                if data[0] != "\x81": return

                end = False

                while True:

                    length = int(binascii.b2a_hex(data[1]),16) & 0x7f 

                    if length < 126:

                        mask = data[2:6]

                        text = data[6:6+length]

                        if 6+length == len(data):

                            end = True

                        else:

                            data = data[6+length:]

                    elif length == 126:

                        length = struct.unpack("!H", data[2:4])[0]

                        mask = data[4:8]

                        text = data[8:8+length]

                        if 8+length == len(data):

                            end = True

                        else:

                            data = data[8+length:]

                    elif length == 127:

                        length = struct.unpack("!Q", data[2:10])[0]

                        mask = data[10:14]

                        text = data[14:14+length]

                        if 14+length == len(data):

                            end = True

                        else:

                            data = data[14+length:]

                    unMaskedText = ""

                    for i,v in enumerate(text):

                        _unMaskedText = hex(int(binascii.b2a_hex(text[i]),16) ^ int(binascii.b2a_hex(mask[i%4]),16))[2:]

                        if len(_unMaskedText) % 2:

                            _unMaskedText = "0" + _unMaskedText

                        unMaskedText += binascii.a2b_hex(_unMaskedText)

                    dataList.append(unMaskedText)

                    if end:

                        break

            return dataList

        def __wrapResponse(self,str):

            response = ""

            if self.__getDraftType() == "76":

                response = '''\x00%s\xFF''' % str

            elif self.__getDraftType() == "10":

                token = "\x81"

                length = len(str)

                if length < 126:

                    token += struct.pack("B", length)

                elif length <= 0xFFFF:

                    token += struct.pack("!BH", 126, length)

                else:

                    token += struct.pack("!BQ", 127, length)

                response = '''%s%s''' % (token,str)

            return response



    所有接收进来的消息,都先过一下parseRequire方法,得到一个明文的数组,如果recv的消息没有合并,数组的长度当然是1,但如果recv的消息是已经合并后的,那么parseRequire会将合并的消息拆解开来,将明文返回出来。

    所有发送的消息,都通过wrapResponse包装一下,再发送回客户端。

    总算是将这头疼的破问题给解决了,希望不要再出差子骚扰我了 @_@,阿门。

  • 相关阅读:
    AVCODEC_MAX_AUDIO_FRAME_SIZE 未定义标识符
    ffmpeg -使用总结
    ubuntu 编译安装ffmpeg
    转-查看Linux CPU个数,核心,线程数
    fpga是什么
    div自适应水平垂直居中的方法
    css百分比问题——`top`、`left`、'translate'的百分比参照谁?
    经典面试题:二分查找/折半查找
    JavaScript预解析
    React--组件
  • 原文地址:https://www.cnblogs.com/cly84920/p/4426569.html
Copyright © 2011-2022 走看看