簡體   English   中英

UDP數據包丟失因包裝大小而異

[英]UDP packet loss differs on package size

我有應用程序在Qt中測試udp套接字。 真的很簡單。 一個套接字綁定到端口並偵聽傳入的軟件包。 其他套接字用於發送程序包。 包裹中的第一個數字是發件人發送的包裹,后續數據僅用於測試。 接收者收到包裹時,它會顯示接收/發送速率。 您可以更改包的大小以及發送包的計時器超時。 我在兩個不同的路由器后面有兩台計算機,我對此進行了測試:

將兩個套接字綁定到同一端口。 將端口轉發添加到該端口。 然后將數據包發送到127.0.0.1和路由器外部ip。

兩台計算機均顯示,收到的軟件包的最大大小為32kb-28b。 28b是UDP標頭大小。 我想。

然后,我嘗試在兩台計算機之間以相同的方式進行測試。 測試以一種方式顯示了相同的結果(例如,當我從comp1發送到comp2時),但是當我從comp2發送到comp1時,最大大小約為3kb(2975b)。 Comp1不會獲得大於此的軟件包。

這是程序代碼:

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();
    }
}

我認為,第一個測試表明,沒有router1,router2,comp1或comp2限制UDP包的最大大小。 但是僅在從comp2到comp1的情況下,最大包裝大小限制為奇數。

問題是為什么?

大多數設備最多支持1500字節左右的MTU / MRU。 您可以發送/接收大於此大小的數據包這一事實意味着您可能一直啟用了巨型幀,或者數據包變得碎片化。

目前尚不清楚您在做什么,但您提到了router external IP 如果兩台計算機位於通過兩個不同的路由器連接到Internet的兩個不同的位置,則發送的超大數據包肯定會被“連接Internet”的路由器分割。

我實際上認為,您可以通過Internet將comp2 32KB數據包發送到comp1comp2了,因為這是您的實際工作,因為必須首先分段的路由器在收到32KB大小的數據包時不會太高興,並且必須將其分解為32 x 1KB的數據包,更不用說接收端了,必須重新組裝它。

我不確定說“測試udp套接字”時您要測試的是什么,但是由於這個原因,大多數網絡測試都是使用小於1518(或1522)字節的數據包執行的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM