为什么我的本地主机丢失了一些数据包?

时间:2019-02-14 17:29:43

标签: python python-2.7 tcp udp

我尝试使用Python 2.7开发服务器和客户端程序,这些程序可以基于此echo程序以UDP或TCP切换:

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 中进行编程,会遇到同样的问题吗?

1 个答案:

答案 0 :(得分:0)

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

此外,您应该考虑到UDP既不能保证包的顺序也不可以保证包的接收,因此您的程序应该考虑到这一点。

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