socket.getInetAddress() return null on Android 5

Refer to last example of "Simple HTTP server running on Android", it work on Xiaomi Redmi 2 running Android 4.4.4. But somebody report program stopped on Android 5 devices. So I re-test on Nexus 7 running Android 5.1.1. Yes, the app crash! caused by NullPointerException, because socket.getInetAddress() return null.


Modify MainActivity.java to capture socket.getInetAddress() before and after close():
package com.blogspot.android_er.androidhttpserver;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

public class MainActivity extends AppCompatActivity {

EditText welcomeMsg;
TextView infoIp;
TextView infoMsg;
String msgLog = "";

ServerSocket httpServerSocket;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

welcomeMsg = (EditText) findViewById(R.id.welcomemsg);
infoIp = (TextView) findViewById(R.id.infoip);
infoMsg = (TextView) findViewById(R.id.msg);

infoIp.setText(getIpAddress() + ":"
+ HttpServerThread.HttpServerPORT + "\n");

HttpServerThread httpServerThread = new HttpServerThread();
httpServerThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

if (httpServerSocket != null) {
try {
httpServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}

private class HttpServerThread extends Thread {

static final int HttpServerPORT = 8888;

@Override
public void run() {
Socket socket = null;

try {
httpServerSocket = new ServerSocket(HttpServerPORT);

while(true){
socket = httpServerSocket.accept();

HttpResponseThread httpResponseThread =
new HttpResponseThread(
socket,
welcomeMsg.getText().toString());
httpResponseThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

private class HttpResponseThread extends Thread {

Socket socket;
String h1;

HttpResponseThread(Socket socket, String msg){
this.socket = socket;
h1 = msg;
}

@Override
public void run() {
BufferedReader is;
PrintWriter os;
String request;

try {
is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
request = is.readLine();

os = new PrintWriter(socket.getOutputStream(), true);

String response =
"<html><head></head>" +
"<body>" +
"<h1>" + h1 + "</h1>" +
"</body></html>";

os.print("HTTP/1.0 200" + "\r\n");
os.print("Content type: text/html" + "\r\n");
os.print("Content length: " + response.length() + "\r\n");
os.print("\r\n");
os.print(response + "\r\n");
os.flush();
InetAddress clientInetAddressBeforeClose = socket.getInetAddress();
socket.close();
InetAddress clientInetAddressAfterClose = socket.getInetAddress();

msgLog += "Request: " + request + "\n";

if(clientInetAddressBeforeClose == null){
msgLog += "clientInetAddressBeforeClose == null\n";
}else{
msgLog += "clientInetAddressBeforeClose = " + clientInetAddressBeforeClose.toString() + "\n";
}

if(clientInetAddressAfterClose == null){
msgLog += "clientInetAddressAfterClose == null\n";
}else{
msgLog += "clientInetAddressAfterClose = " + clientInetAddressAfterClose.toString() + "\n";
}


MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {

infoMsg.setText(msgLog);
}
});

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return;
}
}
}


It's found that on Xiaomi Redmi 2 running Android 4.4.4, socket.getInetAddress() keep no change before and after close().


But on Nexus 7 running Android 5.1.1, change to null after close().


So, we have to read socket.getInetAddress() before close().

socket.getInetAddress() return null on Android 5 socket.getInetAddress() return null on Android 5 Reviewed by Pendik on 06.26 Rating: 5

Tidak ada komentar:

Diberdayakan oleh Blogger.