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

时间:2014-10-19 21:31:50

标签: c++ qt sockets networking

我有应用程序来测试Qt中的udp套接字。这很简单。一个套接字绑定到端口并侦听incomming包。其他套接字用于发送包。包中的第一个数字是发件人发送的包,后续数据仅用于测试。当接收器获得包时,它显示接收/发送速率。您可以改变包大小,以及发送包的计时器超时。我在两台不同的路由器后面有两台计算机,我测试过这样:

将两个套接字绑定到同一端口。添加端口转发到此端口。然后将数据包发送到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的情况下,最大包大小仅限于奇数。

问题是为什么?

1 个答案:

答案 0 :(得分:1)

大多数设备支持最多1500字节的MTU / MRU。您可以发送/接收大于此数据包的事实意味着您要么一直启用巨型帧,要么数据包正在碎片化。

你不是100%清楚自己在做什么,但是你提到了router external IP。如果这两台计算机位于通过两个不同路由器连接到Internet的两个不同位置,那么您发送的超大数据包肯定会被“连接Internet”的路由器分段。

我实际上认为你可以通过互联网从comp1comp2发送32KB数据包真是太了不起了,如果那是你实际在做的事情,因为必须首先将其分段的路由器不会当收到一个32KB大小的数据包并且必须将其分解为32 x 1KB数据包(更不用说接收端)时,它会非常高兴,这将不得不重新组装它。

我不确定当你说'测试udp套接字'时你试图测试到底是什么,但是大多数网络测试都是在这个原因下使用小于1518(或1522)字节的数据包执行的。