代码之家  ›  专栏  ›  技术社区  ›  Naggappan Ramukannan

python套接字连接无法接收完整消息

  •  0
  • Naggappan Ramukannan  · 技术社区  · 7 年前

    我使用以下代码接收数据并转储到文件。但是,当发送的字符超过1500个时,它无法接收完整的消息,因此json在文件中是不正确的。这种情况的发生是不一致的,即有时收到完整的混乱,有时失败。

    但是,如果我们同时使用logstash作为接收器,那么这个问题就不会发生。

    s.listen(5)
    while True:
        c, addr = s.accept()
        print('Got connection from', addr)
        json_data = c.recv(16384).decode() # Increasing this doesn't help
        json_dump = json.dumps(json_data)  
    
        if os.path.exists(destination_file):
            append_write = 'a'  # append if already exists
        else:
            append_write = 'w'  # make a new file if not
        dump_file = open(destination_file, append_write)
        dump_file.write(json_dump + '\n')
        dump_file.close()
    
        c.send(b'SUCCESS')
        c.close()
    

    发送者脚本

    def send_data(socket_conn, data_stream):
        try:
            json_data = JSONEncoder().encode(data_stream)
            json_data = json_data
            socket_conn.send(json_data.encode())
            socket_conn.send(b'\n')
            socket_conn.close()
            return True
        except socket.error as msg:
            logging.error(msg, exc_info=True)
            return False
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Steffen Ullrich    7 年前
      json_data = c.recv(16384).decode() # Increasing this doesn't help
    

    TCP是一种流协议,而不是消息协议。无法保证如果发送方使用单个 send recv .

    如果对等方只发送一个JSON,然后关闭连接,那么接收方可能会 记录 记录 返回空消息)并连接部件:

     data = b''
     while True:
         buf = c.recv(16384)
         if not buf:
             break
         data = data + buf
     json_data = data.decode()
    

    相反,如果对等方正在发送多条“消息”,那么在应用程序级别必须有一些消息指示符,例如,在每条消息前面加上长度前缀(如TLS中的done),在每条消息末尾加上换行符(如SMTP中的done)或类似的标记。然后,收件人需要根据消息格式读取数据,比如首先读取长度,然后读取给定的字节数。

    推荐文章