【问题标题】:Why I have some packets lost in localhost?为什么我在 localhost 中丢失了一些数据包?
【发布时间】:2019-02-14 17:29:42
【问题描述】:

我尝试在 Python 2.7 中开发一个服务器和一个客户端程序,可以在 UDP 或 TCP 中切换,基于这个 echo 程序:

TCP vs. UDP socket latency benchmark

目前,我只是尝试将其编程为本地主机

当我在 TCP 中运行它时(is_UDP = False),服务器程序显示没有丢包(total_perdu = 0)

但如果我在 UDP (is_UDP = True) 中运行它,它会让我丢失一些数据包。

这是我的服务器代码:

import socket
from numpy import *

server_address = ("127.0.0.1", 4444)
client_address = ("127.0.0.1", 4445)
bufferSize  = 4096

# is_UDP = True
is_UDP = False

# Create a datagram socket
if is_UDP == True:
    UDP_Server_Socket_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    UDP_Server_Socket_in.bind(server_address)

    UDP_Server_Socket_out = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    UDP_Server_Socket_out.connect(client_address)

    connection = UDP_Server_Socket_in
    print("UDP server is running...")
else :
    TCP_Server_Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    TCP_Server_Socket.bind(server_address)
    TCP_Server_Socket.listen(1)

    connection, client_address = TCP_Server_Socket.accept()
    print("TCP server is running...")

t = 0
total_perdu = 0
i = 0

while(True):
    i += 1

    # Receive packet from client
    data_2= connection.recv(bufferSize)
    tab=fromstring(data_2,dtype="int32")
    size=len(data_2)

    while size<bufferSize:
        data_2= connection.recv(bufferSize-size)
        size+=len(data_2)

    if data_2:
        perdu=int(tab[0])-t-1
        sperdu=""
        if perdu>0:
            total_perdu+=perdu
            sperdu = "(%d)"%(perdu)

        print "Receive data : %s  %d  %d %s" % (tab[0], len(tab), total_perdu,sperdu)
        t=int(tab[0])

这是我给客户的代码:

import socket
from numpy import *
import time


server_address = ("127.0.0.1", 4444)
client_address = ("127.0.0.1", 4445)

# Packets variables
packet_size = 1024
total_packet = 1000

bufferSize = 4*packet_size


# Variables initialization

error = 0
total_throughput = 0
total_latene = 0
total_ratio = 0
total_stop_time_1 = 0
total_stop_time_3 = 0

# Creation of a packet
send_tab = zeros(packet_size, int)
for i in range(0, packet_size):
    send_tab[i] = i
data_size = (send_tab.size+8)*send_tab.itemsize
print "Data size : %d" % data_size
print "Tab : %s \n" % send_tab

# is_UDP = True
is_UDP = False

# Create a socket at client side
if is_UDP == True:
    UDP_Client_Socket_out = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    UDP_Client_Socket_out.connect(server_address)

    UDP_Client_Socket_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    UDP_Client_Socket_in.bind(client_address)

    connection = UDP_Client_Socket_out
    print("UDP client is running...")
else:
    TCP_Client_Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    TCP_Client_Socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 0)
    TCP_Client_Socket.connect(server_address)
    connection = TCP_Client_Socket
    print("TCP client is running...")

start_time_0 = time.clock()

for packet_number in range(0,total_packet):
    send_tab[0] = packet_number

    # Send packet to server
    start_time=time.clock()
    sent = connection.send(send_tab)
    if sent:
        stop_time_1 = time.clock() - start_time

    # Calculate throughput and ratio
    throughput = data_size / (stop_time_1 * 1000000)

    print "stop_time_1 \t%f" % stop_time_1

    total_throughput += throughput

stop_time_3 = (time.clock() - start_time_0)

print "Results : \n"
print "     Packet error : %d \n" % error
print "     Thoughput: %f Mo/s \n " % (total_throughput/total_packet)
print "     total_stop_time_1 : %f s    \n " % (total_stop_time_1/total_packet)
print "     stop_time_3 : %f \n" % stop_time_3

所以,我有 3 个问题:

  1. 即使我是本地主机也有一些数据包丢失是正常的吗?

  2. 如果是,为什么?

  3. 如果我用 C 编程会不会遇到同样的问题?

【问题讨论】:

  • 为什么不呢? UDP 数据报可能随时丢失。
  • @user207421 : 即使我在同一台计算机上使用客户端和服务器程序?
  • 当然,为什么不呢?它在哪里说不可能发生?

标签: python python-2.7 tcp udp


【解决方案1】:

从您的代码看来,您希望以发送它们的相同顺序接收 UDP 数据包。我不认为您正在丢失数据包,而是服务器接收它们的顺序不是预期的(这对于 UDP 来说是正常的)。

此外,您应该考虑到 UDP 不保证数据包的顺序或接收,因此您的程序应该考虑到这一点。

我会重构代码并将tab 添加到列表中,然后对其进行排序并检查间隙(在传输结束时)。 另一种方法是从服务器发送回复并在客户端上进行检查(但如果您将其部署在 Internet 上,这可能会增加数量)。

【讨论】:

    猜你喜欢
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 2020-05-26
    相关资源
    最近更新 更多