Reputation: 53
I am currently working on a research project that requires me to execute the following protocol in Android:
I have managed to execute this protocol using C (in a Linux environment) and Java (in a Windows environment). However, when I try to do the same thing in Android using the following code, I am unable to send the HTTP GET request after disconnecting and reconnecting to the same Wi-Fi access point.
try {
// executes 3-way handshake
Socket socket = new Socket(InetAddress.getByName("www.google.com"), 80);
// disconnects/reconnects to WiFiAP
WifiManager wifiManager = (WifiManager) baseActivity.getSystemService(Context.WIFI_SERVICE);
wifiManager.disconnect();
Thread.sleep(3000);
wifiManager.reconnect();
Thread.sleep(3000);
// sends HTTP GET request
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println("GET / HTTP/1.1");
pw.println("Host: www.google.com");
pw.println("");
pw.flush();
// prints web server response to display
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String t;
while ((t = br.readLine()) != null) {
outputResults(t);
}
br.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Wireshark shows that the 3-way handshake is successfully executed. However, after disconnecting/reconnecting to the access point, the output stream in never flushed. Initially, I thought the problem might be due to a timeout. However, if instead of disconnecting/reconnecting to the Wi-Fi access point I introduce an equivalent time delay, the code works fine.
I have been stuck on this one for about a week. Any help is greatly appreciate!
Upvotes: 2
Views: 970
Reputation: 12768
Welcome to the Android WiFi socket hell. I usually recognize that the underlying connection have been interrupted by catching th exception and searching into the exception message for the text "broken pipe":
if (socketException.getMessage().toLowerCase().contains("broken pipe")) {
forceReconnection();
}
so forceReconnection()
clear the in/out buffer:
protected void disposeIO() {
// shoutdown socket IO
try {
socket.shutdownInput();
} catch (Exception e) {
}
try {
socket.shutdownOutput();
} catch (Exception e) {
}
try {
this.inputReader.close();
this.inputReader = null;
} catch (Exception e) {
}
// close out stream
try {
outputStream.close();
outputStream = null;
} catch (Exception e) {
}
}
and re-establish the connection to my endpoint calling socket.close()
and recreating socket, the input reader, output stream
Upvotes: 1