我需要在 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,这是模块可传输或可接收的最大段。