Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Data size limit in Android socket transmission?
Forum Updated to NodeBB v4.3 + New Features

Data size limit in Android socket transmission?

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
4 Posts 2 Posters 1.9k 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.
  • X Offline
    X Offline
    xtingray
    wrote on 26 Nov 2017, 19:29 last edited by xtingray
    #1

    Hi!
    I am developing a very basic server-client implementation using Qt. From the server side, I have a Linux server. This is the main part of the code:

    Server::Server() : QObject()
    {
        server = new QTcpServer(this);
        connect(server, SIGNAL(newConnection()), this, SLOT(sendFile()));
    
        if (!server->listen(QHostAddress::Any, 8080))
            qDebug() << "Server could not start!";
        else
            qDebug() << "Server started!";
    }
    
    void Server::sendFile()
    {
        QTcpSocket *socket = server->nextPendingConnection();
    
        QString path = "/home/data/file.bin";
        QFile file(path);
        if (file.open(QIODevice::ReadOnly)) {
            QByteArray data = file.readAll();
            qint64 fileSize = file.size();
            int length = 128;
            int index = 0;
    
            while (index < fileSize) {
                QByteArray segment = data.mid(index, length);
                qint64 result = socket->write(segment);
                if (result == -1) {
                    qDebug() << "Error while writing data";
                } else {
                    if ((index + length) == fileSize) {
                        break;
                    } else {
                        index += length;
                        if ((index + length) > fileSize)
                            length = fileSize - index;
                    }
                }
            }
        } else {
            qDebug() << "Couldn't read file -> " << path;
        }
    
        socket->disconnectFromHost();
        file.close();
    }
    

    From the (Android) client side, this is the main part of the code:

    Client::Client() : QObject()
    {
        socket = new QTcpSocket;
        socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
        socket->connectToHost("192.168.1.1", 8080, QIODevice::ReadWrite);
        connect(socket, SIGNAL(connected()), this, SLOT(initFile()));
        connect(socket, SIGNAL(readyRead()), this, SLOT(readFileFromServer()));
        connect(socket, SIGNAL(disconnected()), this, SLOT(closeFile()));
    }
    void Client::initFile()
    {
        QString filename = "/path/to/file.bin";
        file = new QFile(filename);
    
        if (!file->open(QIODevice::WriteOnly)) {
            #ifdef TUP_DEBUG
                qDebug() << "Insufficient permissions to create file -> " << file.fileName();
            #endif
        }
    }
    
    void Client::readFileFromServer()
    {
        while (true) {
            QByteArray data = socket->read(64);
            if (data.isEmpty())
                break;
            file->write(data);
        }
    }
    
    void Client::closeFile()
    {
        file->close();
        qDebug() << "File saved!";
    }
    

    Initially I started running some tests between two computers using Linux. The code works like a charm and I can transmit any file through the network without any issue.
    Now, when I tried the same test but running the client from my cellphone running Android, I detected an strange issue: If the file I am transmitting is larger than 14480 bytes, then, the file is limited to that size and the rest of the data is lost.
    To confirm the constraint, I sent several files with different sizes and the constant value is evident for every case: 14480 bytes.

    Looking for an answer I started to google for that number and I found that this limitation is related to some TCP/IP parameter: https://en.wikipedia.org/wiki/Maximum_segment_size

    Any way, if I want to transmit files bigger than 14460 bytes to Android devices, what should I do? Any suggestion?

    Thanks!


    Qt Developer

    A 1 Reply Last reply 26 Nov 2017, 20:03
    0
    • X xtingray
      26 Nov 2017, 19:29

      Hi!
      I am developing a very basic server-client implementation using Qt. From the server side, I have a Linux server. This is the main part of the code:

      Server::Server() : QObject()
      {
          server = new QTcpServer(this);
          connect(server, SIGNAL(newConnection()), this, SLOT(sendFile()));
      
          if (!server->listen(QHostAddress::Any, 8080))
              qDebug() << "Server could not start!";
          else
              qDebug() << "Server started!";
      }
      
      void Server::sendFile()
      {
          QTcpSocket *socket = server->nextPendingConnection();
      
          QString path = "/home/data/file.bin";
          QFile file(path);
          if (file.open(QIODevice::ReadOnly)) {
              QByteArray data = file.readAll();
              qint64 fileSize = file.size();
              int length = 128;
              int index = 0;
      
              while (index < fileSize) {
                  QByteArray segment = data.mid(index, length);
                  qint64 result = socket->write(segment);
                  if (result == -1) {
                      qDebug() << "Error while writing data";
                  } else {
                      if ((index + length) == fileSize) {
                          break;
                      } else {
                          index += length;
                          if ((index + length) > fileSize)
                              length = fileSize - index;
                      }
                  }
              }
          } else {
              qDebug() << "Couldn't read file -> " << path;
          }
      
          socket->disconnectFromHost();
          file.close();
      }
      

      From the (Android) client side, this is the main part of the code:

      Client::Client() : QObject()
      {
          socket = new QTcpSocket;
          socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
          socket->connectToHost("192.168.1.1", 8080, QIODevice::ReadWrite);
          connect(socket, SIGNAL(connected()), this, SLOT(initFile()));
          connect(socket, SIGNAL(readyRead()), this, SLOT(readFileFromServer()));
          connect(socket, SIGNAL(disconnected()), this, SLOT(closeFile()));
      }
      void Client::initFile()
      {
          QString filename = "/path/to/file.bin";
          file = new QFile(filename);
      
          if (!file->open(QIODevice::WriteOnly)) {
              #ifdef TUP_DEBUG
                  qDebug() << "Insufficient permissions to create file -> " << file.fileName();
              #endif
          }
      }
      
      void Client::readFileFromServer()
      {
          while (true) {
              QByteArray data = socket->read(64);
              if (data.isEmpty())
                  break;
              file->write(data);
          }
      }
      
      void Client::closeFile()
      {
          file->close();
          qDebug() << "File saved!";
      }
      

      Initially I started running some tests between two computers using Linux. The code works like a charm and I can transmit any file through the network without any issue.
      Now, when I tried the same test but running the client from my cellphone running Android, I detected an strange issue: If the file I am transmitting is larger than 14480 bytes, then, the file is limited to that size and the rest of the data is lost.
      To confirm the constraint, I sent several files with different sizes and the constant value is evident for every case: 14480 bytes.

      Looking for an answer I started to google for that number and I found that this limitation is related to some TCP/IP parameter: https://en.wikipedia.org/wiki/Maximum_segment_size

      Any way, if I want to transmit files bigger than 14460 bytes to Android devices, what should I do? Any suggestion?

      Thanks!

      A Offline
      A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on 26 Nov 2017, 20:03 last edited by
      #2

      @xtingray

      How did you connect the devices? is there a router between linux and android?

      if I were you, I'd start Wireshark on the Linux machine and compare the communication to the second Linux vs. Android. Dont know if you can run a packet sniffer on Android too? that might give some more insight.

      Btw: why don't you use an established protocol like ftp or http for file transfer?

      Qt has to stay free or it will die.

      X 1 Reply Last reply 27 Nov 2017, 01:42
      1
      • A aha_1980
        26 Nov 2017, 20:03

        @xtingray

        How did you connect the devices? is there a router between linux and android?

        if I were you, I'd start Wireshark on the Linux machine and compare the communication to the second Linux vs. Android. Dont know if you can run a packet sniffer on Android too? that might give some more insight.

        Btw: why don't you use an established protocol like ftp or http for file transfer?

        X Offline
        X Offline
        xtingray
        wrote on 27 Nov 2017, 01:42 last edited by xtingray
        #3

        Btw: why don't you use an established protocol like ftp or http for file transfer?

        You are right. I am going to take a look to Qt WebSockets to enhance my implementation.

        PS: Talking to Android developers, they told me about a native class called AsyncTask, commonly used by them to do actions like download a file from a given URL.
        You will find more info about it in this link:
        https://developer.android.com/reference/android/os/AsyncTask.html

        The key to deal with network requirements from Android using Qt, seems to be work with threads. I wonder if using QThread I can make a work-around for this problem.


        Qt Developer

        1 Reply Last reply
        0
        • X Offline
          X Offline
          xtingray
          wrote on 29 Nov 2017, 13:24 last edited by xtingray
          #4

          Making a little experimentation, I decided to mix this example I found in the Qt documentation:
          http://doc.qt.io/qt-5/qtnetwork-download-example.html
          With this article about threads:
          https://wiki.qt.io/QThreads_general_usage
          So, basically I took an http request and I execute it from a thread. The result is really interesting, I could transmit files bigger than 14480 bytes.

          In most of the cases, the size of the transmitted files is the same, including the md5 hash. In other few, the downloaded file is a little bigger than the original but just for few bytes, I don't know why.

          Anyway, my new approach is a lot better than the first one. Definitive solution? I think I need to run more tests ;)


          Qt Developer

          1 Reply Last reply
          1

          1/4

          26 Nov 2017, 19:29

          • Login

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