TCP与UDP套接字延迟基准

Mic*_*ner 6 python sockets udp tcp

我已经为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()
Run Code Online (Sandbox Code Playgroud)

因此,您可以运行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()
Run Code Online (Sandbox Code Playgroud)

与服务器一样,您可以通过benchmark_TCP()或启动基准测试benchmark_UDP()

对于TCP,结果约为25 µs对于 Unix,结果约为54 µs,对于Windows,甚至更糟(TCP约为30 µs,UDP超过200 µs)。为什么?我希望UDP具有最小的优势。

Dav*_*rtz 6

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

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