python立即发送TCP / IP数据

时间:2016-06-15 04:00:21

标签: python sockets tcp network-programming

我目前正在myserver中通过TCP / IP发送数据

for str in lst:
  data = str + "\n"
  self._conn.sendall(data)

现在假设我的列表中包含以下两个字符串

1-This is statement 1 in list
2-This is statement 2 in list

我的客户正在收到第2行的一半。

   This is statement 1 in list
   This is 

我想分别在列表中发送line1然后再发送第2行。我知道TCP / IP以这种方式工作,它将发送可用于发送的整个数据。我想我可以在致电self._conn.sendall(data)后延迟,但我想知道我还有其他选择。我无法更改数据的接收者,我只能对发件人进行更改。到目前为止,我唯一的选择是在每次发送后添加延迟。

3 个答案:

答案 0 :(得分:5)

TCP可以处理数据流,而不是单个数据包。这就像从文件中读取数据一样。发送方将数据放入其发送缓冲区,TCP可以自行决定何时发送数据。到达接收应用程序的时间取决于数据发送的时间和(通常是不可预测的)网络条件。

如果在套接字中使用TCP_NODELAY标志(如socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)之类的话),则TCP交付可以更加可预测。这会导致TCP在数据到达其缓冲区时立即发送数据。但是但是,到达时间并不能得到保证。这就是为什么任何基于时间的解决方案都会破裂,至少在某些情况下是这样。

解决方案是自己将数据流分成块。有几种方法可以做到这一点。以下是一些:

  1. 使用固定长度的消息 - 如果所有消息都有固定的长度,接收者只需要recv()正确的字节数,处理消息,然后等待相同的字节数。

  2. 在每封邮件之前发送邮件的长度。如果你想发送字符串" blah",请将其编码为" 0004blah"或类似的东西。接收器将(总是)读取前四个字节(为0004)以计算要读取的剩余字节数。然后它将读取所需的字节数,处理消息,然后等待下一个字节。它是一个强大的解决方案,也很容易实现。

  3. 使用分隔符。文本文件中的行除以换行符(\n)。同样,您可以在消息之间添加特殊的分隔符字节(或字节)。例如,您可以定义消息始终以美元符号($)结尾。然后所有接收器必须做的是从插槽逐字节读取,直到它收到一个美元符号。当然,如果你采用这种方法,你必须确保消息的正文不包含分隔符。

答案 1 :(得分:0)

TCP基于流,而不是单个消息。所以你需要自己解析每条消息的终点。在你的情况下,一个想法是阅读,直到你得到换行符,然后处理该行。请注意,您可能会读到这个:

This is statement 1 in list
This is 

然后你需要检查你是否有换行符,处理该行,然后让你的缓冲区准备好接收其余部分,如下所示:

This is 

答案 2 :(得分:0)

TCP有一个本地缓冲区,在它已满之前不会被发送。您可以强制刷新本地缓冲区,以便在每条消息之后发送它,但是当另一方收到这些包时,它们会被存储在另一个本地缓冲区中,您的分离可能会消失。 TCP是一个流,将其用作流。您必须使用分隔符,并且在收到数据包时,您必须手动分离消息。如果您想要更多控制,请使用UDP数据包。