简体   繁体   English

UDP数据包丢失因包装大小而异

[英]UDP packet loss differs on package size

I have application to test udp sockets in Qt. 我有应用程序在Qt中测试udp套接字。 It is really simple. 真的很简单。 One socket binds to port and listens incomming packages. 一个套接字绑定到端口并侦听传入的软件包。 Other socket is used to send packages. 其他套接字用于发送程序包。 First number in package is packages sent from sender, subsequent data is just for test. 包裹中的第一个数字是发件人发送的包裹,后续数据仅用于测试。 When receiver gets package it shows received/sent rate. 接收者收到包裹时,它会显示接收/发送速率。 You can vary package size, and timeout of timer to send packages. 您可以更改包的大小以及发送包的计时器超时。 And I have two computers behind two different routers, which I tested like this: 我在两个不同的路由器后面有两台计算机,我对此进行了测试:

Bind both sockets to same port. 将两个套接字绑定到同一端口。 Add port forwarding to this port. 将端口转发添加到该端口。 Then send packets to 127.0.0.1 and to router external ip. 然后将数据包发送到127.0.0.1和路由器外部ip。

Both computers showed, that maximum size of package received is 32kb - 28b. 两台计算机均显示,收到的软件包的最大大小为32kb-28b。 28b is UDP header size. 28b是UDP标头大小。 I suppose. 我想。

Then I try to test in the same way between two computers. 然后,我尝试在两台计算机之间以相同的方式进行测试。 And test shows same results in one way(for example when I send from comp1 to comp2), but when I send from comp2 to comp1 maximum size is around 3kb(2975b). 测试以一种方式显示了相同的结果(例如,当我从comp1发送到comp2时),但是当我从comp2发送到comp1时,最大大小约为3kb(2975b)。 Comp1 does not get package larger than this. Comp1不会获得大于此的软件包。

This is code of program: 这是程序代码:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    receiveSocket(),
    sendSocket(),
    timer(),
    packetSend(0),
    packetReceived(0),
    address(),
    sendPort(63465), 
    receivePort(62345),
{
    ui->setupUi(this);

    timer.setSingleShot(false);
    timer.setInterval(100);

    receiveSocket.bind(receivePort);

    connect(&timer, SIGNAL(timeout()), this, SLOT(sendData()));
    connect(&receiveSocket, SIGNAL(readyRead()), this, SLOT(receiveData()));

    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startStopSend()));
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::receiveData()
{
    unsigned int otherSideSent = 0;
    do
    {
        receiveDatagram.resize(receiveSocket.pendingDatagramSize());
        receiveSocket.readDatagram(receiveDatagram.data(), receiveDatagram.size());
    }while(receiveSocket.hasPendingDatagrams());

    QDataStream in(&receiveDatagram, QIODevice::ReadOnly);
    in >> otherSideSent;

    float tempVal;
    std::vector<float> value;
    for (int i=0; i<receiveDatagram.size()/8 - 1;i++ )
    {
        in >> tempVal;
        value.push_back(tempVal);
    }

    packetReceived++;

    ui->packetData->setText(QString("I receive/you sent:     ")+QString::number(packetReceived)+QString("/")+QString::number(otherSideSent));
}


void MainWindow::sendData()
{
    QDataStream out(&sendDatagram, QIODevice::WriteOnly);
    out << ++packetSend;
    for(unsigned int i = 0; i < 8185; ++i)
    {
        out << 1.0 + i/100.0;
    }

    sendSocket.writeDatagram(sendDatagram, address, sendPort);
}


void MainWindow::startStopSend()
{
    if(!timer.isActive())
    {
        address.setAddress(ui->ipLine->text());
        timer.start();
    }
    else
    {
        timer.stop();
    }
}

First test, I think, showed that none router1, router2, comp1 or comp2 limits maximum size of UDP package. 我认为,第一个测试表明,没有router1,router2,comp1或comp2限制UDP包的最大大小。 But only in case from comp2 to comp1 maximum package size is limited to strange number. 但是仅在从comp2到comp1的情况下,最大包装大小限制为奇数。

Question is Why? 问题是为什么?

Most devices support MTU/MRU up to around 1500 bytes. 大多数设备最多支持1500字节左右的MTU / MRU。 The fact that you can send/receive packets larger than this means you either have jumbo frames enabled all the way through, or packets are getting fragmented. 您可以发送/接收大于此大小的数据包这一事实意味着您可能一直启用了巨型帧,或者数据包变得碎片化。

It isn't 100% clear what you are doing, but you mentioned router external IP . 目前尚不清楚您在做什么,但您提到了router external IP If the two computers are sitting on two different locations connected to the Internet via two different routers, the oversized packets that you are sending will most definitely be fragmented by the routers that "connect the Internet". 如果两台计算机位于通过两个不同的路由器连接到Internet的两个不同的位置,则发送的超大数据包肯定会被“连接Internet”的路由器分割。

I actually think it's amazing that you can send 32KB packet from comp1 to comp2 via the Internet, if that's what you are actually doing, because the router that has to firstly fragment it won't be too happy when it receives a 32KB sized packet and have to fragment it down to, say, 32 x 1KB packets, not to mention the receiving end, that will have to reassemble it. 我实际上认为,您可以通过Internet将comp2 32KB数据包发送到comp1comp2了,因为这是您的实际工作,因为必须首先分段的路由器在收到32KB大小的数据包时不会太高兴,并且必须将其分解为32 x 1KB的数据包,更不用说接收端了,必须重新组装它。

I am not sure what exactly it is that you are trying to test when you say 'to test udp sockets', but most network tests are performed with packets sizes less than 1518 (or 1522) bytes for this reason. 我不确定说“测试udp套接字”时您要测试的是什么,但是由于这个原因,大多数网络测试都是使用小于1518(或1522)字节的数据包执行的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM