【问题标题】:Slow Python socket transfers慢速 Python 套接字传输
【发布时间】:2016-07-01 21:44:34
【问题描述】:

我有一个关于 Python 套接字编程的问题。我对套接字很陌生,可能对它们的工作原理了解甚少。我需要在运行 python 应用程序时在两台机器之间传输二进制文件,并认为做一些套接字编程会比做系统命令 scp 或 netcat 更好/更快。但由于某种原因,如果我在我的机器之间传输一个 1GB 的图像,大约需要 14 秒。如果我通过 SCP 完成它只需要大约 9 个。这似乎很奇怪,因为 SCP 是出了名的慢。我希望我的传输速度可以与 netcat 相媲美,但我无法实现这一目标。

服务器:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 50000))
s.listen(1)

img = open('test.img', 'rb')

client, addr = s.accept()
l = img.read(4096)

while(l):
        client.send(l)
        l = img.read(4096)

img.close()
s.close()

客户:

host = ''
port = 50000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

img = open('./newimg.img', 'wb')

l = s.recv(4096)

while(l):
    img.write(l)
    l = s.recv(4096)

img.close()
s.close()

这显然是非常基本的,缺少很多功能和异常处理,但它至少可以传输一个文件(虽然速度很慢)。我显然已经从我的代码中删除了一些细节,比如“主机”变量。

我该如何改进?

谢谢!

【问题讨论】:

  • 尝试设置 TCP_NODELAY。如果发送/接收阻塞有问题,那么它可能会有所帮助。

标签: python python-2.7 sockets


【解决方案1】:

我建议将缓冲区的大小从 4096 增加到更大的大小。这样会减少item的次数,会减少经过堆栈操作的次数和Python的解释,这可能会提高数据传输的速度。

目前,在读取 4096 (4K) 字节时,您将从套接字对 1 GB 文件进行 262144 次读取/写入。如果您可以将缓冲区增加到一个 1048576 字节(1024K),那么对于一个 1 GB 的文件,只有 1024 次来自套接字和文件的读/写。这将使系统调用的优化代码做更多的工作。由于我不知道有多少 RAM 内存可用,因此可能有助于使其尽可能大,但留出一些内存以留出一点余地。

例如,在我使用的一个系统中,我们发送了少量数据并且无法获得我们预期的性能。我们在一个较大的消息中排列了一堆少量数据,并且能够获得我们需要的性能。从最好的情况来看,我们可以确定我们正在花费大量时间调用系统函数,这些函数在堆栈中来回进行少量是问题的一部分。

但是,scp 可能仍然可能更快,因为它是编译的机器代码并且即使它有额外的开销也没有要经过的解释。

【讨论】:

    【解决方案2】:

    使 s.recv() 的缓冲区大小更大,以便一次接收更多字节

    【讨论】:

      猜你喜欢
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 2010-11-13
      • 2011-10-13
      • 1970-01-01
      相关资源
      最近更新 更多