Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QUdp packets loss at reciver.
Forum Updated to NodeBB v4.3 + New Features

QUdp packets loss at reciver.

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 418 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JustSoleSoleJ Offline
    JustSoleSoleJ Offline
    JustSoleSole
    wrote on last edited by
    #1

    Hi all,
    Im trying to use QUdpSocket to transmit some images from clinet to server,which are about 0.5~1.5MB.
    And i found i cant pack the image data in one packet(it`s too big).
    So i divide them into several pieces,each piece is about 4096 bytes.
    The clinet shows that my image is divided into about 380+ pieces,but at my server,there is almost half packets loss.

    Struct UdpDatagramHead:

    const int UdpDatagramMaxSize = 4096;
    
    ///Udp
    typedef struct
    {
    	int nDataTotalSize;		
    	int nDatagramIndex; 
    	int nDatagramSize;	
    	int nOffset;		
    	int nIsColor;		
    	int nWidth;
    	int nHeight;
    	char cDatagram[UdpDatagramMaxSize];
    }UdpDatagramHead;
    

    Clinet send code

    //datagram is QByteArray,whose size is like 0.5~1.5MB
    int nDataSize = datagram.size();
    int nOffset = 0;
    int nIndex = 0;
    QByteArray qbtPacket;
    while (nDataSize > 0)
    {
    	UdpDatagramHead objUdpHead;
    	objUdpHead.nOffset = nOffset;
    	if (nDataSize > UdpDatagramMaxSize)
    	{
    		qbtPacket = datagram.mid(nOffset, UdpDatagramMaxSize);
    		nOffset   += UdpDatagramMaxSize;
    		nDataSize -= UdpDatagramMaxSize;
    	}
    	else
    	{
    		qbtPacket = datagram.mid(nOffset, nDataSize);
    		nOffset += nDataSize;
    		nDataSize = 0;
    	}
    	qDebug() << nIndex;
    	objUdpHead.nDataSize = nDataSize;
    	objUdpHead.nDatagramIndex = nIndex++;
    	objUdpHead.nDatagramSize = qbtPacket.size();
    	objUdpHead.nIsColor = nIsColor;
    	objUdpHead.nWidth = nWidth;
    	objUdpHead.nHeight = nHeight;
    	memcpy(objUdpHead.cDatagram, qbtPacket.data(), sizeof(char));
    
    	nWriteSize = m_pUdpSocket->writeDatagram((char*)&objUdpHead, sizeof(objUdpHead), host, port);
    	m_pUdpSocket->waitForBytesWritten();
    	qbtPacket.clear();
    }
    

    Server recive code:

    const int cDataSize = UdpDatagramMaxSize + sizeof(UdpDatagramHead);
    char cDatagram[cDataSize];
    while (m_pUdpSocket->hasPendingDatagrams())
    {
    	int nPendingDataSize = m_pUdpSocket->pendingDatagramSize();
    	m_pUdpSocket->readDatagram(cDatagram, nPendingDataSize);
    	UdpDatagramHead * pUdpHead = (UdpDatagramHead *)cDatagram;
    	if (pUdpHead)
    	{
    		memcpy(m_cImgData + pUdpHead->nOffset, pUdpHead->cDatagram, pUdpHead->nDatagramSize);
    		qDebug() << pUdpHead->nDatagramIndex;
    		if (pUdpHead->nDatagramIndex * UdpDatagramMaxSize + pUdpHead->nDatagramSize == pUdpHead->nDataSize)
    		{
    			uchar * din = (uchar *)m_cImgData;
    			if (pUdpHead->nIsColor)
    			{
    				m_objImg = QImage(din, pUdpHead->nWidth, pUdpHead->nHeight, QImage::Format_RGB888);
    			}
    			else
    			{
    				m_objImg = QImage(din, pUdpHead->nWidth, pUdpHead->nHeight, QImage::Format_Grayscale8);
    			}
    			double dFps = m_objFps.CaculateFps();
    			emit Signal_ShowImage(pUdpHead->nIsColor, dFps);
    		}
    	}
    }
    

    Why my reciver packets loss so heavy?

    1 Reply Last reply
    0
    • JustSoleSoleJ Offline
      JustSoleSoleJ Offline
      JustSoleSole
      wrote on last edited by
      #6

      Solved by this:

      connect(m_pUdpSocket, &QUdpSocket::bytesWritten, this, &QUdpClient::Slot_RefillSocketBuffer);
      
      1 Reply Last reply
      0
      • C Offline
        C Offline
        ChrisW67
        wrote on last edited by
        #2

        UDP provides no guarantee of delivery, ordering, congestion control, or duplicate protection. Any transient (or permanent) network condition might cause lost packets. In your case it is likely the datagram size exceeds the IP MTU causing datagram fragmentation. If one fragment is lost, then entire datagram is lost.

        If you want reliability then use TCP or implement your own re-transmission mechanism

        JustSoleSoleJ 1 Reply Last reply
        2
        • C ChrisW67

          UDP provides no guarantee of delivery, ordering, congestion control, or duplicate protection. Any transient (or permanent) network condition might cause lost packets. In your case it is likely the datagram size exceeds the IP MTU causing datagram fragmentation. If one fragment is lost, then entire datagram is lost.

          If you want reliability then use TCP or implement your own re-transmission mechanism

          JustSoleSoleJ Offline
          JustSoleSoleJ Offline
          JustSoleSole
          wrote on last edited by
          #3

          @ChrisW67
          Actually ive already done one project using Tcp,so now im trying to use Udp to make it.
          And compare the difference between these two solutions.
          Now i need to learn more about Udp and try to establish my own re-transmission mechanism.
          For this problem,what kinds of re-transmission mechanism are more suitable?
          Others told me to use buffer at reciver which can save every packet,each packet has its own serial number,during some time reciver checks if there are some packets loss.And then send re-transmission.
          Or sliding window protocol???
          Any advices are benefit for me,
          Thanks!!!

          1 Reply Last reply
          0
          • hskoglundH Offline
            hskoglundH Offline
            hskoglund
            wrote on last edited by
            #4

            Hi, good you learn about UDP because it is gaining popularity (and TCP is slooooowly going away like FTP or Gopher).
            For an implementation of robust and safe transmission over UDP you can look at HTTP/3

            JustSoleSoleJ 1 Reply Last reply
            1
            • hskoglundH hskoglund

              Hi, good you learn about UDP because it is gaining popularity (and TCP is slooooowly going away like FTP or Gopher).
              For an implementation of robust and safe transmission over UDP you can look at HTTP/3

              JustSoleSoleJ Offline
              JustSoleSoleJ Offline
              JustSoleSole
              wrote on last edited by
              #5

              @hskoglund
              Thanks for your advice,i looked HTTP/3 just now,getting it uses Udp instead of Tcp to decrease RTT.
              Back to my problem,i still need to solve images are too big to send in one packet but should be cut into plenty of pieces.
              So my core question is how sender divide, and how recvier package,and,most important,congestion control and re-transmission.
              So complicated for a newbie like me who dont have any experience on client communicates with server.

              1 Reply Last reply
              0
              • JustSoleSoleJ Offline
                JustSoleSoleJ Offline
                JustSoleSole
                wrote on last edited by
                #6

                Solved by this:

                connect(m_pUdpSocket, &QUdpSocket::bytesWritten, this, &QUdpClient::Slot_RefillSocketBuffer);
                
                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved