【问题标题】:Python optimize packets in sending. How to prevent it?Python 在发送中优化数据包。如何预防?
【发布时间】:2016-12-28 15:57:23
【问题描述】:

我正在尝试使用 python 套接字一个接一个地发送 3 个数据包。 Python 将其优化为一到两个数据包。 我通过 sleep 命令阻止了它,但它需要很长时间。 我想打开TCP urg标志,有人知道怎么做吗?

或者你有另一个独奏?

客户端:

import socket
from time import sleep

IP = '127.0.0.1'
PORT = 5081
BUFFER_SIZE = 1024


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IP, PORT))

s.send('1'*5)
#sleep( 1)
s.send('2'*5)
#sleep( 1)
s.send('3'*5)

s.close()

服务器端:

import socket

IP = '0.0.0.0'
PORT = 5081
BUFFER_SIZE = 1024


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((IP, PORT))
s.listen(1)

connection, address = s.accept()
while 1:
    #Here I expected to get the 1nd value
    data1 = connection.recv(BUFFER_SIZE)
    #end of communication
    if not data1:
        break
    print 'data1', data1

    #Here I expected to get the 2nd value,but both inputs arrived here, 22222 and 33333
    data2  = connection.recv(BUFFER_SIZE)
    print 'data2', data2

    #Here I expected to get the 3nd value
    data3  = connection.recv(BUFFER_SIZE)
    print 'data3', data3

connection.close()

谢谢 Avinoam

【问题讨论】:

  • 为什么在设置缓冲区大小为 1024 时期望得到 5 个字节?
  • 禁用 NAGLE 算法:s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
  • @thebjorn - recv 采用最大缓冲区大小,但如果这就是套接字接收缓冲区中的全部内容,则很高兴返回更小的块。它不会等待 1024 字节。
  • @SteffenUllrich - 这还不足以阻止缓冲区的聚合。 TCP 是一种流协议,会在发送方和接收方双方折叠缓冲区。
  • @tdelaney:您对缓冲区(应用内或内核内)是正确的,但问题是关于数据包(在线上)。禁用 NAGLE 后,发送者内核至少会尝试立即将数据作为数据包发送,而不是等待更多数据。但是,如果内核套接字缓冲区中仍有数据要发送(未完成的 ACK、小窗口...),它当然会将新数据与仍未发送的数据合并。当然 TCP 是流式传输的,因此您不能使用 send/recv 自己处理消息,但您需要实现自己的消息封装。

标签: python python-2.7 sockets tcp tcp-ip


【解决方案1】:

你甚至不应该尝试。 TCP 是流协议,应该用作流协议(意味着单个字节序列)。即使您在您的系统上使用 localhost 时设法保持数据包的分离,但如果您在不同的主机之间使用它,或者只是在升级 TCP/IP 堆栈之后使用它,它也可能会中断。一旦您的数据包通过代理或软件过滤器,任何事情都可能发生。

在流上分离不同对象的正确方法是使用上层协议对对象发送方进行编码并在客户端对它们进行解码。一个例子是一个或两个字节(如果超过一个字节,则按网络顺序)的大小,后跟相关字节。或者你可以想象一个带有命令、标题和数据的文本协议,或者[把你想要的任何东西放在这里]

【讨论】:

  • 交换机不会改变数据包。路由器可能会在 IP 层对 TCP 数据包进行分段,但不会导致 TCP 数据包大小的变化,因为 IP 分段也在 IP 层(即 TCP 之下)的内核中重新组装。但是像代理这样的东西可能会导致更高层的变化,从而改变数据包的大小。 MTU 设置和 PMTU 也可能影响数据包大小。除此之外,我完全同意你的观点,即 TCP 不应该被视为消息协议,而只能被视为字节流。
  • @SteffenUllrich:感谢您的评论。我已经用它编辑了我的帖子...
猜你喜欢
  • 1970-01-01
  • 2018-09-21
  • 1970-01-01
  • 2017-06-25
  • 2021-04-26
  • 1970-01-01
  • 2013-09-15
  • 2012-04-29
相关资源
最近更新 更多