【问题标题】:TCP sockets unable to send messages in a burstTCP 套接字无法突发发送消息
【发布时间】:2014-11-20 01:19:46
【问题描述】:

您好,我有多个系统使用 TCP 连接通过消息进行通信。

我的发送函数如下所示

def _send(self, message, dest):

    self.sendLock.acquire()
    message = pickle.dumps(message)
    #sending length
    message_length = len(message)
    self.outChan[dest].send('<MESSAGELENGTH>%s</MESSAGELENGTH>'
                            % str(message_length))

    for message_i in range(0, message_length, 1024):
        self.outChan[dest].send(message[:1024])
        message = message[1024:]

    self.sendLock.release()

接收线程如下所示:

def readlines(self, sock):

    while True:

        msg = ''

        opTag = '<MESSAGELENGTH>'
        clTag = '</MESSAGELENGTH>'

        while not all(tag in msg for tag in (opTag, clTag)):
            msg = sock.recv(1024)

        msglen = int(msg.split(clTag)[0].split(opTag)[1])
        msg = msg.split(clTag)[1]

        while len(msg) < msglen:
            msg += sock.recv(msglen-len(msg))

        self.rec.put(pickle.loads(msg))

从 self.rec 读取消息后,会向发件人发送确认消息。

我已经实现了自己的缓冲区来控制网络中的流量。在任何时候,我都会发送最多 MAX_BUFFER_SIZE 条消息而没有收到确认。

问题来了:程序启动时,不等待确认就发送MAX_BUFFER_SIZE消息。但是只有少数这些 MAX_BUFFER_SIZE 消息被接收。

在其中一个 MAX_BUFFER_SIZE = 5 的模拟中,总共发送了 100 条消息,但未收到 m2、m3 和 m4。已收到所有其他消息(按发送顺序)。

我怀疑错误是在初始发送突发中,但我无法找出确切的问题。

【问题讨论】:

    标签: python sockets networking tcp


    【解决方案1】:

    接收线程有几个错误:

    1. 在检查接收到的消息的开始和结束标记时,您不会附加到已经接收到的部分,而是覆盖它。

    2. 检测到消息长度后,您将丢失后续消息,这些消息的结束标记已收到,但尚未分析。

    3. 您可能将多条消息放在self.rec 中。

    这是一个更正的表格,cmets 解释了这些变化:

    def readlines(self, sock):
    
        msg = '' # initialize outside since otherwise remiander of previous message would be lost
    
        opTag = '<MESSAGELENGTH>' # no need to repeat this in each iteration
        clTag = '</MESSAGELENGTH>' # no need to repeat this in each iteration
    
        while True:
    
            while not all(tag in msg for tag in (opTag, clTag)):
                msg += sock.recv(1024) # += rather than =
    
            msglen = int(msg.split(clTag)[0].split(opTag)[1])
            msg = msg.split(clTag, 1)[1] # split just once, starting from the left
    
            while len(msg) < msglen:
                msg += sock.recv(msglen-len(msg))
    
            self.rec.put(pickle.loads(msg[:maglen])) # handle just one message
            msg = msg[msglen:] # prepare for handling future messages
    

    【讨论】:

      猜你喜欢
      • 2019-03-31
      • 2015-02-07
      • 1970-01-01
      • 2012-03-25
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多