我正在开发一个 Android 应用程序来控制 Arduino MKR1000 板,通过 TCP/IP 网络协议进行通信。当有客户端可用时,Arduino 用作接入点并发送数据。我的 Android 应用程序设法连接到 Arduino 的 WiFi shield,但在 Android 端实现 TCP 客户端时遇到问题。事实上,当我尝试连接指定端口号上的 Socket 时,在指定主机上,我得到了一个 Socket 异常。
我已经看到了一些答案:
java.net.SocketException:软件导致连接中止:recv 失败,出现 java.net.SocketException:连接重置
java.net.SocketException:软件导致连接中止:连接
但我一直无法弄清楚如何解决这个问题。
套接字异常:
W/System.err: java.net.SocketException: Software caused connection abort
W/System.err: at java.net.PlainSocketImpl.socketConnect(Native Method)
W/System.err: at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:334)
W/System.err: at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196)
W/System.err: at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
W/System.err: at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
W/System.err: at java.net.Socket.connect(Socket.java:586)
W/System.err: at java.net.Socket.connect(Socket.java:535)
W/System.err: at java.net.Socket.<init>(Socket.java:427)
W/System.err: at java.net.Socket.<init>(Socket.java:243)
W/System.err: at com.progetto.xxxxx.arduino.MyIntentService.onHandleIntent(MyIntentService.java:69)
W/System.err: at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:67)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.os.HandlerThread.run(HandlerThread.java:61)
安卓代码:
TCP 客户端
public class MyIntentService extends IntentService {
Socket mSocket = null;
public static final int PORT = 2390;
InetAddress local = null;
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
try {
local = InetAddress.getByName("192.168.1.7");
mSocket=new Socket(local,PORT); // Exception occurs
Log.i(TAG, "socket");
} catch (UnknownHostException e) {
Log.i(TAG, "UNknownHost");
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "IOEXCeption");
}
}
}
主要活动
public class MainActivity extends AppCompatActivity {
BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION))
{
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo!=null)
{
String ssidN = wifiInfo.getSSID();
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean connected = info.isConnected();
if (connected)
{
if (ssidN.contains(ssid))
{
startService(intents);
}
}
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiManager.disconnect();
wifiManager.setWifiEnabled(true);
intents=new Intent(this,MyIntentService.class);
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
}
public void WifiAp(){
LayoutInflater layoutInflater=getLayoutInflater();
view_pass=layoutInflater.inflate(R.layout.wifi_item,null);
Log.i(TAG, "view");
txt_annulla=(TextView)view_pass.findViewById(R.id.txt_annulla);
txt_connetti=(TextView)view_pass.findViewById(R.id.txt_connetti);
final android.app.AlertDialog.Builder alertDialog=new android.app.AlertDialog.Builder(this);
alertDialog.setView(view_pass);
final android.app.AlertDialog dialog = alertDialog.create();
Window window = dialog.getWindow();
window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
window.setGravity(Gravity.CENTER);
dialog.show();
txt_annulla.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
txt_connetti.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wifiManager.disconnect();
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + ssid + "\"";
conf.status = WifiConfiguration.Status.ENABLED;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
int newNetworkId = wifiManager.addNetwork(conf);
//Adds to the list of network and returns the network id which can be used to enable it later.
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
if (i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, true);
wifiManager.reconnect();
break;
}
}
dialog.dismiss();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.power:
WifiAp();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
Arduino代码:
#include <SPI.h>
#include <WiFi101.h>
#include <Arduino.h>
char apssid[] = "WifiMkr";
IPAddress ipC(192, 168, 1, 7);
int status = WL_IDLE_STATUS;
unsigned int localport = 2390;
//IPAddress remoteIp;
unsigned long timeM=0;
WiFiServer server(localport);
WiFiClient client;
IPAddress ip;
unsigned long tsample=1;
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait for serial port to connect. Needed for native USB port only
}
Serial.println("Access Point");
if (WiFi.status() == WL_NO_SHIELD)
{
Serial.println("WiFi shield non è presente");
}
WiFi.config(ipC);
Serial.println("Creating access point named: ");
Serial.println(apssid);
if (WiFi.beginAP(apssid) != WL_AP_LISTENING) {
Serial.println("Creating access point failed");
}else{
Serial.println("Creating access point success");
}
delay(1000);
server.begin();
printWiFiStatus();
// compare the previous status to the current status
Serial.println("\nStarting connection to server...");
}
void loop() {
unsigned long time=millis();
if (status != WiFi.status()) {
//it has changed update the variable
status = WiFi.status();
if (status == WL_AP_CONNECTED)
{
byte remoteMac[6];
// a device has connected to the AP
Serial.print("Device connected to AP, MAC address: ");
WiFi.APClientMacAddress(remoteMac);
Serial.print(remoteMac[5], HEX);
Serial.print(":");
Serial.print(remoteMac[4], HEX);
Serial.print(":");
Serial.print(remoteMac[3], HEX);
Serial.print(":");
Serial.print(remoteMac[2], HEX);
Serial.print(":");
Serial.print(remoteMac[1], HEX);
Serial.print(":");
Serial.println(remoteMac[0], HEX);
}
else
{
// a device has disconnected from the AP, and we are back in listening mode
Serial.println("Device disconnected from AP");
}
}
client= server.available();
if(client){
Serial.println("hello client");
while(client.connected()){
//
int value = analogRead(A3);
client.write(value);
Serial.println("millis");
Serial.println(tsample);
Serial.println(millis());
Serial.println(timeM);
while(millis()<timeM+tsample);
}
}
}
void printWiFiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
// print where to go in a browser:
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
}