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

时间:2018-12-07 08:21:45

标签: sockets buffer python-sockets

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

但是如果我们同时使用logstash作为接收者,则不会出现theis问题。

接收方脚本:

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 个答案:

答案 0 :(得分:1)

  json_data = c.recv(16384).decode() # Increasing this doesn't help

TCP是流协议,而不是消息协议。无法保证如果发送方使用单个send发送所有数据,则可以使用单个recv来接收它们。

如果对等方仅发送一个JSON,然后关闭连接,则接收方可能只是recv,直到没有更多数据可用(recv返回空消息)并连接各个部分:

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

如果相反,对等方正在发送多个“消息”,则在应用程序级别上必须有一些消息指示符,例如,给每个消息加上一个长度(如TLS中完成),为每个消息以换行符结尾(如中SMTP)或类似。接收者然后需要根据消息格式读取数据,例如首先读取长度,然后读取给定的字节数。