TCP-связь между модулем WiFi и приложением Android

Мне нужно реализовать TCP-связь между Wifi-модулем SPWF01SA (от ST Microelectronics) и приложением для Android. Для прошивки модуля Wi-Fi я использую библиотеку промежуточного программного обеспеченияX-Cube-WIFI в качестве сокета сервера, в то время как в Android у меня есть AsyncTask в качестве сокета клиента. Модуль Wi-Fi управляется микро stm32f103 (используя интерфейс I2C), и они оба подключены к точке доступа. Вот код сокета клиента Android для инициализации / чтения-сокета и записи-сокета:

@Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
    boolean result = false;

    try {
        Log.i("AsyncTask", "doInBackground: Creating socket");
        //Get a List of IPs that have a the desired port opened

        SocketAddress sockaddr = new InetSocketAddress(MY_IP, PORT);
        nsocket = new Socket();
        nsocket.connect(sockaddr, 5000); //10 second connection timeout
        if (nsocket.isConnected()) {
            nsocket.setSendBufferSize(250);
            nis = nsocket.getInputStream();
            nos = nsocket.getOutputStream();
            Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
            Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
            byte[] buffer = new byte[4096];
            int read = nis.read(buffer, 0, 4096); //This is blocking
            publishType = PUBLISH_READ;
            while(read != -1){
                byte[] tempdata = new byte[read];
                System.arraycopy(buffer, 0, tempdata, 0, read);
                publishProgress(tempdata);
                Log.i("AsyncTask", "doInBackground: Got some data");
                read = nis.read(buffer, 0, 4096); //This is blocking
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.i("AsyncTask", "doInBackground: IOException");
        result = true;
    } catch (Exception e) {
        e.printStackTrace();
        Log.i("AsyncTask", "doInBackground: Exception");
        result = true;
    } finally {
        try {
            nis.close();
            nos.close();
            nsocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.i("AsyncTask", "doInBackground: Finished");
    }
    return result;
}

public boolean sendDataToNetwork(final String cmd)
{
    if (nsocket.isConnected())
    {
        Log.i("AsyncTask", "SendDataToNetwork: Writing received message to socket");
        new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    nos.write(cmd.getBytes());
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception");
                }
            }
        }).start();

        return true;
    }

    Log.i("AsyncTask", "SendDataToNetwork: Cannot send message. Socket is closed");
    return false;
}

Для записи в сокет небольшого размера (от Android до модуля) все работает, проблема возникает, когда мне нужно отправить более 512 байт (ведь это буфер rx модуля wifi). Если я посылаю больше, чем это в модуль Wi-Fi, его буфер RX идет на переполнение. Я думал, что строка nsocket.setSendBufferSize(250) поможет, но не имеет значения. Как я могу передать в модуль Wi-Fi большое количество данных, если последний имеет небольшой буфер приемника? Я новичок в реализации TCP, спасибо за ваше время.


Другая информация:

Модуль Wi-Fi управляется через интерфейс I2C микроконтроллером STM32F103RB, а библиотека Middlware предоставляется непосредственно ST(я разместил ссылку на begeing).


После отладки программного обеспечения на микро, который соединяется с модулем Wi-Fi, я увидел, что есть два сбоя, которые происходят быстро:

  • либо переполнение буфера в I2C Rx

  • или пока он читает буфер rx, он может пропустить некоторые команды I2C от модулей wifi, которые служат для чтения текущего ожидающего пакета в буфере i2c rx;

Скорость I2C между Wi-Fi-модулем и Micro установлена ​​на 460800 кбит / с. Похоже, проблема заключается в том, что поток TCP с Android слишком быстрый. Вот некоторые спецификации для связи модуля Wi-Fi (предоставлено командой STM):

  • Размер буфера модуля Wi-Fi составляет 1 КБ (такой же на микро);

  • Для TCP MSS (максимальный размер сегмента) равен 730B (фиксировано в опциях стека lwip). Таким образом, как для TX, так и для RX, это максимальный сегмент, передаваемый или получаемый модулем.

ST Microelectronics подтверждают, что, разбив данные на пакеты по 100B, они достигли 60 кБ / с. Как я могу замедлить поток из приложения для Android и исправить MSS меньше или равным 730B?

0 ответов

Другие вопросы по тегам