WiFi模块和Android应用程序之间的TCP通信

时间:2016-04-26 16:16:22

标签: android tcp iot tcpsocket

我需要在 SPWF01SA Wifi-Module (来自ST Microelectronics)和Android应用之间实现TCP通信。对于Wifi模块固件,我使用 X-Cube-WIFI Middleware library作为服务器套接字,而在Android中我有一个AsyncTask作为客户端套接字。 wifi模块由stm32f103 micro(使用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到模块)一切正常,当我需要发送超过512bytes(女巫是wifi模块rx缓冲区)时问题就会出现。如果我向wifi模块发送更多信息,其RX缓冲区将继续溢出。我想, nsocket.setSendBufferSize(250)这一行会成功,但并没有任何区别。如果后者有一个小的接收缓冲区,我怎样才能向wifi模块传输大量数据? 我是TCP实施的新手,谢谢你的时间。

其他信息:

WiFi模块由 STM32F103RB 微控制器通过I2C接口控制,而Middlware库由ST直接提供(我已经在beginging上发布了链接)。

在与wifi模块通信的micro上对软件进行了重新调试后,我发现有两个故障发生了:

  • I2C Rx缓冲区溢出

  • 或者当它读取rx缓冲区时,它可能会错过来自wifi模块的一些I2C命令,用于读取i2c rx缓冲区上的当前待处理数据包;

wifi模块和micro之间的I2C速率设置为460800kbps。 两者中的任何一个,问题似乎是来自android的TCP流太快了。以下是wifi模块通信的一些规范(由STM团队提供):

  • Wifi模块缓冲区大小为1Kb(微观上相同);

  • 对于TCP,MSS(最大段大小)等于730B(在lwip堆栈选项中固定)。因此,对于TX和RX,这是模块可传输或可接收的最大段。

ST Microelectronics确认,通过将数据分成100B数据包,它们达到了60kB / s。 如何减慢Android应用程序的流速,并修复小于或等于730B的MSS?

0 个答案:

没有答案