【问题标题】:TCP vs. UDP socket latency benchmarkTCP 与 UDP 套接字延迟基准测试
【发布时间】:2015-12-15 18:03:38
【问题描述】:

我已经在 Python 中实现了通过 TCP 和 UDP 进行套接字通信的小型基准测试。令人惊讶的是,TCP 的速度几乎是 UDP 的两倍。

为了避免路由效应,服务器和客户端运行在同一台 Unix 机器上,但在不同的线程上。

也许代码很有用。这是服务器代码:

import socket
import sys

host = 'localhost'  
port = 8888
buffersize = 8
server_address = (host, port) 

def start_UDP_server():
    socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    socket_UDP.bind(server_address)

    print("UDP server is running...")

    while True:
        data, from_address = socket_UDP.recvfrom(buffersize)
        if not data: break
        socket_UDP.sendto(data, from_address)
    socket_UDP.close()


def start_TCP_server():
    socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket_TCP.bind(server_address)
    socket_TCP.listen(1)

    print("TCP server is running...")

    while True:    
        client, client_address = socket_TCP.accept()

        while True:
            data = client.recv(buffersize)
            if not data: break
            client.sendall(data)

        client.close()

因此您可以运行start_TCP_server()start_UDP_server()

在客户端,代码是:

import socket
import sys
import time

host = 'localhost'  
port = 8888
buffersize = 8
server_address = (host, port) 
client_address = (host, port+1)
N = 1000000


def benchmark_UDP():
    socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    socket_UDP.bind(client_address)

    print("Benchmark UDP...")

    duration = 0.0
    for i in range(0, N):
        b = bytes("a"*buffersize, "utf-8")
        start = time.time()
        socket_UDP.sendto(b, server_address)
        data, from_address = socket_UDP.recvfrom(buffersize)
        duration += time.time() - start

        if data != b:
            print("Error: Sent and received data are bot the same")

    print(duration*pow(10, 6)/N, "µs for UDP") 


def benchmark_TCP():
    socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket_TCP.connect(server_address)

    print("Benchmark TCP...")

    duration = 0.0
    for i in range(0, N):
        b = bytes("a"*buffersize, "utf-8")
        start = time.time()
        socket_TCP.sendall(b)
        data = socket_TCP.recv(buffersize)
        duration += time.time() - start

        if data != b:
            print("Error: Sent and received data are bot the same")

    print(duration*pow(10, 6)/N, "µs for TCP")
    socket_TCP.close()

对于服务器,您可以通过benchmark_TCP()benchmark_UDP() 启动基准测试。

结果在 Unix 上约为 25 µs 对于 TCP,而对于 UDP 约为 54 µs,在 Windows 上甚至更糟(TCP 约 30 µs,超过 200 µs对于 UDP)。为什么?我预计 UDP 的优势很小。

【问题讨论】:

  • 可能与您发送的数据大小和 MTU 大小有关 see here
  • 不,因为我的问题不是关于吞吐量,而是软件开销(避免网络配置问题等)。我想测量一个 ping-pong 消息 10^6 次,而不是通过电线可以按下多少字节。这是否更清楚?
  • 这有点像苹果和橘子。对于 UDP,您每次都发送到一个套接字,这意味着每次发送/接收都将主机名解析为 IP 地址等。对于 TCP,您只需设置一次连接,然后每次都通过该连接发送数据。如果对于 TCP,您将连接设置/关闭放在循环中,它可能更像是橘子 vs 塞维利亚。但无论哪种方式,您的单一延迟指标仅反映 UDP 与 TCP 的一个方面 - 延迟 - 但还有其他因素,如可靠性和吞吐量也很重要。
  • 关于barny的评论,把buffersize提升到64000,看看谁是TCP或UDP的赢家
  • Rolf of Saxony - “获胜” - 如果您只想发送 32 个字节,那么用 64k 衡量性能并用它来宣布获胜者有什么意义? @Michale Dorner 的测试还略过了 UDP 可能不如 TCP 可靠的事实——但在单台机器内进行测试不太可能暴露交付可靠性方面的差异。这是适合您的指标 - 您需要先了解测量的情况,然后才能开始比较结果。

标签: python sockets tcp udp


【解决方案1】:

您的 TCP 套接字已连接,但您的 UDP 套接字未连接。这意味着对 UDP 套接字上的每个发送/接收进行额外处理。在 UDP 套接字上调用 each side 上的 connect,就像在 TCP 套接字上调用 connect/accept 一样。

iperf 这样的程序这样做是为了准确测量。

【讨论】:

  • iperf 不提供 TCP 往返测量。
  • 你完全正确。尽管 UDP 是无连接的,using this code 导致 24 µs 用于 UDP25 µs 用于 TCP
  • 对于 buffersize = 8000 而不是之前的 8 个,我们得到 TCP 28 µs 和 UDP 30 µs。
  • 这是否意味着 TCP 比没有连接的 UDP“更好/更快”?是否可以链接有关此的更多信息?实际上,我在阅读的所有文档中从未见过这样的声明。我只关心速度,所以我的问题是:对于很多发送和接收来说,全球和每次发送什么速度更快? (TCP / UDP / "UDP 连接"/ ...)
  • @Waroulolz 嗯,它们各有优缺点。在未连接的套接字上发送 UDP 数据报时的一个缺点是,必须在每个发送的数据报上完成本地探测到目标所需的工作。
猜你喜欢
  • 2013-07-13
  • 2020-12-23
  • 2013-03-13
  • 2020-12-17
  • 2010-11-14
  • 2020-07-02
  • 2021-04-16
  • 1970-01-01
  • 2018-10-12
相关资源
最近更新 更多