Python套接字一次接收多个数据包

3
当我将我的Python客户端连接到服务器时,会向客户端发送两个数据包:
第一个数据包是:
FD 01

第二个:

FF 66 46 3E 61 37 07 CA 0B

然而,当我试图通过套接字在Python客户端接收它们时,我会同时接收到两个:

FD 01 FF 66 46 3E 61 37 07 CA 0B

我希望能够连续将数据包接收到我的缓冲区中,这样我就可以解析一个数据包,在后台执行一些操作,然后解析队列中的另一个数据包。我该如何解决这个问题?
这是我的客户端代码:
class ReceivePacket():
    def __init__(self, bytes):
        reply = str(bytes).encode('hex')
        print "<- [{}] - {}".format(headers.RECV.get(int(reply[:2], 16), int(reply[:2], 16)),
                                    ' '.join([reply[i:i + 2] for i in range(0, len(reply), 2)]).upper())

class Client(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

        self.size = 1024
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # type: socket.socket

        self.buf = bytearray(self.size)

        self.net = network.Network()
        self.net.bindClient(self)

        try:
            self.sock.connect((HOST, AUTH_PORT))
        except socket.error, msg:
            raise

    def run(self):
        while True:
            reply = self.sock.recv_into(memoryview(self.buf))

            if reply:
                self.receive(reply)

    def receive(self, nbytes):
        ReceivePacket(self.buf) # Having FD 01 FF 66 46 3E 61 37 07 CA 0B here

c = Client()
c.start()
2个回答

1
你可以在所有的字节数组前添加后续字节数组的长度,就像在TCP/UDP数据包中定义自己的头部一样。对于你的字节流来说,一个字节似乎足够容纳后面消息的大小。
你的字节流将看起来像这样: 02 FD 01 09 FF 66 46 3E 61 37 07 CA 0B 结果是这样的: 02 FD 01 09 FF 66 46 3E 61 37 07 CA 0B 这允许你在缓冲区中接收所有数据,然后处理后面的n个字节。
如果你还想要能够随机处理数据包顺序,你可能还想在头部加入第二个字节来定义消息类型。那么生成的字节流将如下所示: [长度|类型|数据]

0
另一个解决方案是使用pickle序列化您的数据包,例如在读取时自动将每个数据包单独处理。
“只需将pickles连接起来即可,Python知道每个pickles的结束位置” 就像这样:
>>> import cStringIO as stringio
>>> import cPickle as pickle
>>> o1 = {}
>>> o2 = []
>>> o3 = ()
>>> p = pickle.dumps(o1)+pickle.dumps(o2)+pickle.dumps(o3)
>>> s = stringio.StringIO(p)
>>> pickle.load(s)
{}
>>> pickle.load(s)
[]
>>> pickle.load(s)
()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接