java.net.SocketException in Android AsyncTask - android

I am now working on creating simple
image server in Android.
This is the server class...
new Thread(new Runnable()
{
public void run()
{
try
{
ServerSocket serverSocket = new ServerSocket(8080);
while(true)
{
Socket client = serverSocket.accept();
SimpleImageSender sender
= new SimpleImageSender(client);
sender.execute();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}).start();
and this is the AsyncTask.
public class SimpleImageSender extends HttpGetForMapTileHandler<Void,Void,Void>
{
protected Socket client;
public SimpleImageSender(Socket socket)
{
super();
this.client = socket;
}
#Override
protected Void doInBackground(Void... params)
{
try
{
URL url = new URL("http://www.imageFromWeb.png");
HttpURLConnection httpCon = (HttpURLConnection)url.openConnection();
httpCon.setRequestMethod("GET");
httpCon.connect();
if(httpCon.getResponseCode() == 200)
{
DataOutputStream out = new DataOutputStream(this.client.getOutputStream());
byte response[] = new byte[BUFFER_SIZE];
int index = httpCon.getInputStream().read(response,0,BUFFER_SIZE);
while(index != -1)
{
out.write(response,0,index);//***
index = httpCon.getInputStream().read(response,0,BUFFER_SIZE);
}
out.flush();
}
else
{
Log.d("AAA","No png");
}
}
catch(Exception e)
{
e.printStackTrace();
cancel(true);
}
return null;
}
}
When I tested this code in Android 6.0(Nexus 5), Java.net.SocketException
occers when the line //*** called more than twice.
This is the call stack I got.
09-06 18:03:42.763 20730-22167/com.example.SimpleImageSenderServer
W/System.err: java.net.SocketException: sendto failed: ECONNRESET
(Connection reset by peer)
09-06 18:03:42.763 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at
libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:542)
09-06 18:03:42.763 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:511)
09-06 18:03:42.764 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at
java.net.PlainSocketImpl.write(PlainSocketImpl.java:500)
09-06 18:03:42.764 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at java.net.PlainSocketImpl.-
wrap1(PlainSocketImpl.java)
09-06 18:03:42.764 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at
java.net.PlainSocketImpl$PlainSocketOutputStream.
write(PlainSocketImpl.java:266)
09-06 18:03:42.764 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at
java.io.DataOutputStream.write(DataOutputStream.java:98)
09-06 18:03:42.765 20730-22167/com.example.SimpleImageSenderServer
W/System.err: at
com.example.SimpleImageSenderServer.
SimpleImageSender.doInBackground(SimpleImageSender.java:xx)
I also want to imform that this error did not happen when I tested in
Android 4.4.2, 5.0 devices.
Virtual devices (Android 7.0).
I checked the java.net.SocketException issues through
the Internet but I could not figure it out
what was the cause.
Any advice will be very helpful.
Thank you

You can never to thread operations on the main thread. It has to be done async.
So you have two options. Either disable strictmode:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Or use an asynctask for the connection too

int index = httpCon.getInputStream().read(response,0,BUFFER_SIZE);
while(index != -1)
{
out.write(response,0,index);//***
index = httpCon.getInputStream().read(response,0,BUFFER_SIZE);
}
This is garbage, or at least poorly written and poorly named. read() returns a count, not an index. Try this:
int count;
while((count = httpCon.getInputStream().read(response)) > 0)
{
out.write(response,0,count);
}
// The following are completey missing from your code
out.close();
httpCon.getInputStream().close();
If you still get connection resets it is probably because the peer has closed the connection.

Related

Bluetooth Code to send string In Android

I have got list of paired devices of Bluetooth.Now i want to send text to that particular paired device.I have done code for that.
Below is the code:
private void init() throws IOException {
BluetoothAdapter blueAdapter = BluetoothAdapter.getDefaultAdapter();
if (blueAdapter != null) {
if (blueAdapter.isEnabled()) {
Set<BluetoothDevice> bondedDevices = blueAdapter.getBondedDevices();
if(bondedDevices.size() > 0) {
Object[] devices = (Object []) bondedDevices.toArray();
BluetoothDevice device = (BluetoothDevice) devices[position];
ParcelUuid[] uuids = device.getUuids();
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid());
socket.connect();
outputStream = socket.getOutputStream();
inStream = socket.getInputStream();
}
Log.e("error", "No appropriate paired devices.");
} else {
Log.e("error", "Bluetooth is disabled.");
}
}
}
public void write(String s) throws IOException {
outputStream.write(s.getBytes());
}
public void run() {
final int BUFFER_SIZE = 1024;
byte[] buffer = new byte[BUFFER_SIZE];
int bytes = 0;
int b = BUFFER_SIZE;
while (true) {
try {
bytes = inStream.read(buffer, bytes, BUFFER_SIZE - bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
But i'm getting these Error:
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
04-05 10:53:41.356 5580-5580/? W/System.err: at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:900)
04-05 10:53:41.356 5580-5580/? W/System.err: at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:912)
04-05 10:53:41.356 5580-5580/? W/System.err: at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:531)
So, please help me how to solve this error.
What kind of device are you trying to connect to?
-> Based on discussion: If trying to connect to another phone running Android there must be application which is accepting the connection. Working example is available from Google: BluetoothChat
You can try speeding up the connection process:
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
Or you can try using different UUID (are there more supported)?
System.out.println(uuids);
Or you can try using insecure connection:
device.createInsecureRfcommSocketToServiceRecord(...)
BTW: Your code for reading data from inpust stream won't work very well. Take a look at example from Google Chat Application: BluetoothChatService

Android Client not able to connect to server in libgdx game

I need to connect to a server I've set up on my Mac, but the Android socket always fails to connect. If I run the libgdx game on my Mac and use "localhost" as the desired server to connect to, it works fine. I've included the relevant permissions in my Manifest file. I'm using the public ip address I found by just doing a google search for my ip. I've made sure the ports are consistent as well.
public class ClientServer implements AsyncTask<String> {
private int port;
private String serverAddress;
private DataOutputStream outStream;
//private DataInputStream inStream;
private MandelSample ms;
public ClientServer (String serverAddress, int port, MandelSample ms) {
this.serverAddress = serverAddress;
this.port = port;
this.ms = ms;
}
public String fetchData (MandelSample ms) {
SocketHints hints = new SocketHints();
Socket clientSocket = Gdx.net.newClientSocket(Protocol.TCP, serverAddress, port, hints);
outStream = new DataOutputStream(clientSocket.getOutputStream());
String messageIN="Default Message";
try {
outStream.write("This message is from Android".getBytes());
messageIN = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())).readLine();
} catch (IOException e) {
Gdx.app.log("ClientServer", "An error occured", e);
}
return messageIN;
}
#Override
public String call() throws Exception {
String s = fetchData(ms);
return s;
}
}
My logcat:
com.badlogic.gdx.utils.GdxRuntimeException: Error making a socket connection to 146.7.4.78:8080
02-24 09:51:59.872 16349-26646/com.mygdx.game W/System.err: at com.badlogic.gdx.net.NetJavaSocketImpl.<init>(NetJavaSocketImpl.java:51)
02-24 09:51:59.872 16349-26646/com.mygdx.game W/System.err: at com.badlogic.gdx.backends.android.AndroidNet.newClientSocket(AndroidNet.java:70)
02-24 09:51:59.872 16349-26646/com.mygdx.game W/System.err: at com.mygdx.game.ClientServer$override.fetchData(ClientServer.java:35)
02-24 09:51:59.872 16349-26646/com.mygdx.game W/System.err: at com.mygdx.game.ClientServer$override.access$dispatch(ClientServer.java)
02-24 09:51:59.873 16349-26646/com.mygdx.game W/System.err: at com.mygdx.game.ClientServer.fetchData(ClientServer.java:0)

Android socket connection refused error

I want to implement socket connection between 2 deceives , client keep sending GPS data to the server and I need both of it run in new thread , the client send first one data then keep show error like this
03-18 16:35:11.805: E/Client run:(8163): java.net.ConnectException: failed to connect to /192.168.2.103 (port 5678): connect failed: ECONNREFUSED (Connection refused)
here is the client code
public class Send implements Runnable{
private boolean Connect = true;
public void Connect(){
Connect = true;
}
public void Disconnect(){
Connect = false;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(Connect){
try {
SocketClient = new Socket("192.168.2.103", 5678);
ObjectOutputStream oos = new ObjectOutputStream(SocketClient.getOutputStream());
oos.writeDouble(GPSinfo[2]);
//ObjectInputStream ois = new ObjectInputStream(SocketClient.getInputStream());
//ois.readInt();
oos.close();
//ois.close();
} catch (Exception e) {
Log.e("Client run: ", e.toString());
}
}
}
}
here is server code
public class Receive implements Runnable{
private boolean CanReceive = true;
private double Data;
public void Connect(){
CanReceive = true;
}
public void Disconnect(){
CanReceive = false;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(CanReceive){
try {
SocketServer = new ServerSocket(5678);
Socket connectedSocket = SocketServer.accept();
ObjectInputStream ois = new ObjectInputStream(connectedSocket.getInputStream());
Data = ois.readDouble();
DataText.setText("" + Data);
//ObjectOutputStream oos = new ObjectOutputStream(connectedSocket.getOutputStream());
//oos.writeInt(1);
//ois.close();
//oos.close();
} catch (Exception e) {
Log.e("Server run: ", e.toString());
}
}
}
}
by the way , the both code is inner class , and INTERNET permission is added.
It's obvious it's not a router-firewall related problem as you are under the same net, so there are only a few possibilities:
There's nothing listening on that port on that IP on the server-side
There's a local firewall on the server-side that is blocking that connection attempt
You are not using WIFI so you're not under the same net.
You should make sure you can open that service some ther way, that would help you debugging where the culprit is. If you've already done this, I'd suggest using some debugging tool to trace TCP packets (I don't know either what kind of operating system you use on the destination machine; if it's some linux distribution, tcpdump might help, in Win environments WireShark works just good).
This isn't a 'data transfer error'. This is a 'connection refused' error. It means the server you want to transfer the data to or from isn't running at the IP:port you specified.
Try killing the adb service before you begin the connection. I had a similar problem and killing the adb service before the connection resolved the issue.
I had the same error. I simply used ServerSocket and it worked well.
ServerSocket socket = new ServerSocket(8888);

Android Asynctask method does not display the data

I tried to display data(string) from android device to java desktop server application. I was successful in that. I tried to find wifi signal strength from wifi access point to android device. I did that too. Now, I need to integrate this both thing.
First, is the client code where I find the signal strength and pass it to server. First, I run the server. It runs and waits. As soon as I run the client the signal strength from 1st router is displayed and then the app crashes. I have given the error log.
It crashes because of Async method in the client. This Async task code works well when I try to send string from android mobile to java desktop server. But, here it gives me an error. I think, I have made some simple error.
Client.java
package com.example.temp;
public class MainActivity extends Activity {
private Socket client;
private PrintWriter printwriter;
private EditText textField;
private Button button;
private String messsage;
StringBuilder sb = new StringBuilder();
public final static String extra = "com.example.temp.MESSAGE";
protected static final long TIME_DELAY = 5000;
TextView mTextView;
Handler handler=new Handler();
int count =0; String data ="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text_id);
handler.post(updateTextRunnable);
messsage=mTextView.getText().toString();
new Asynctask().execute(messsage);
}
Runnable updateTextRunnable = new Runnable() {
public void run() {
if (count < 5) {
WifiManager mainWifiObj;
mainWifiObj = (WifiManager) getSystemService(Context.WIFI_SERVICE);
class WifiScanReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
}
}
WifiScanReceiver wifiReciever = new WifiScanReceiver();
registerReceiver(wifiReciever, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
List<ScanResult> wifiScanList = mainWifiObj.getScanResults();
for (ScanResult result : wifiScanList) {
if (result.SSID.equals("Dal-WPA2")) {
sb.append(result.level);
}
if (result.SSID.equals("eduroam")) {
sb.append(result.level);
}
if (result.SSID.equals("Dal")) {
sb.append(result.level);
}
}
count++; mTextView.setText("getting called " +count + sb);
} else {
}
//----------------code here to send values to java server---
handler.postDelayed(this, TIME_DELAY);
}
};
class Asynctask extends AsyncTask<String, Void, Void> {
private static final String IP_ADDRESS = "134.190.162.165";
private static final int DEST_PORT = 4444;
private EditText mTextField;
protected Void doInBackground(String... messages) {
// if (messages.length != 1) { return null; }
String message = messages[0];
Socket client = null;
try {
client = new Socket(IP_ADDRESS, DEST_PORT); // connect to server
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Write to server.
try {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage); // write the message to output stream
printwriter.flush();
printwriter.close();
}
catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
}
The Error from the log cat I found is : It is in the Async task here.
>FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
android.os.AsyncTask$3.done(AsyncTask.java:278)
java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
java.util.concurrent.FutureTask.setException(FutureTask.java:124)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
java.util.concurrent.FutureTask.run(FutureTask.java:137)
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
com.example.temp.MainActivity$Asynctask.doInBackground(MainActivity.java:114)
com.example.temp.MainActivity$Asynctask.doInBackground(MainActivity.java:1)
android.os.AsyncTask$2.call(AsyncTask.java:264)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
Activity com.example.temp.MainActivity has leaked IntentReceiver com.example.temp.MainActivity $1$1WifiScanReceiver#41756998 that was originally registered here. Are you missing a call to unregisterReceiver()?
02-17 15:13:52.771: E/ActivityThread(25738): android.app.IntentReceiverLeaked: Activity com.example.temp.MainActivity has leaked IntentReceiver com.example.temp.MainActivity$1$1WifiScanReceiver#41756998 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:763)
android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:567)
android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1167)
android.app.ContextImpl.registerReceiver(ContextImpl.java:1154)
android.app.ContextImpl.registerReceiver(ContextImpl.java:1148)
android.content.ContextWrapper.registerReceiver(ContextWrapper.java:348)
com.example.temp.MainActivity$1.run(MainActivity.java:58)
android.os.Handler.handleCallback(Handler.java:605)
android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
android.app.ActivityThread.main(ActivityThread.java:4517)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
The server just waits for the response and displays the data. With simple string it displays the data But here, the client crashes so, it is not possible. So, I assume that client code is perfect.
There is no compile time error only run time. In the run(), I call Async method and then do handler.postdelayed, so that code runs again after few second. But it runs correctly till Asynctask class is called In the Async task, it gives me error.
I am new. It would be great if someone can point out my mistake.
I tried but I am not getting what I should do. I think my logic is correct as individual parts are running. But dont know why async task is not running here.
Thank you in advance.
Edited : The print writer and other sockets closed.
Still getting the same error.
I have just used class Asynctask and not public class Asycntask, hope there wont be any problem in this.
I just understand from the log file that error is in asynctask background , but exactly the error is not understandable also.
I dont know where I am getting wrong.
Thanks for the help.
fdvkfdnvkkfdnb fdkvj nfdvnjfdknv fdvnfdvnkdfnv fdjkvnfdkjvnjkfdn
fdjvfdjkv fdvndfkjvn fdlvnkdfvn fdkvnfdnvk fdvknfdkvn
fdvklmfd fdkv flkk fdkvkfl fdkkklvklfdm flvmalsvmaslvv
dfvkfdlkv f lkfdv fdlkvmfdklvm fdvkfdklv dfklvlfdknvkfdnv
dfvknfdklvn dfkvfdkvn fdkvnfdkvn dfkkvnfdknv dfjkvnfdkjnv
My guess is that the problem arises because you are not properly closing client and printwriter. (You need to close all streams for the socket as well as the socket itself.) On repeated executions, the AsyncTask tries to open a new socket and eventually the OS runs out of resources for doing so because of this failure to close. The call to new Socket(...) throws an exception (which you catch) but then client remains null. Since you don't return after the exception, you then get a NullPointerException. My guess is that this NullPointerException is what's responsible for the app crash. (This really is just a guess; the info in the error you posted is quite sparse.)
Try this code instead:
public class Asynctask extends AsyncTask<String, Void, Void> {
private EditText mTextField;
protected Void doInBackground(String... messages) {
String message = messages[0];
Socket client = null;
try {
client = new Socket(IP_ADDRESS, DEST_PORT);
} catch (IOException e) {
e.printStackTrace();
return null;
}
try {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage);
}
catch (IOException e) {
e.printStackTrace();
} finally {
if (printwriter != null) {
try {
printwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
printwriter = null;
}
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}

Android NullPointerException being thrown in Synchronized Method

I have an android app written in java.
The app basically connects to a device which sends the app messages. The app waits for the messages to come in and then reports them, before processing each message.
I have a Connection class and a Listener class.
The Connection class is started via the constructor, which sets up the Listener class to listen for messages coming in from the device.
When a message comes in, the Listener sends the message to a method in the Connection class, reportMessage(). This is where the message is processed.
The Listener class is on a separate thread.
The code is shown below.
public class Connection
{
private String response;
private String newResponse;
private DataInputStream reader;
private DataOutputStream writer;
private Socket socket;
private boolean keepListening;
private Listener listener;
public Connection (String _ipAddress, int portNumber)
{
try
{
socket = new Socket(_ipAddress, _port); //Connect to the server and its socket
writer = new DataOutputStream(socket.getOutputStream()); //Connect to the server to receive and send messages
reader = new DataInputStream(socket.getInputStream());
listener = new Listener(reader, this); //Create a new listener for the client
new Thread(listener).start(); //Set the listener off running
}
catch (Exception e)
{
...
}
}
public synchronized void reportMessage(String message)
{
try
{
if("".equals(newResponse))
{
newResponse = new String();
}
newResponse = newResponse + message;
System.out.println("Message Received: " + newResponse);
processMessage(); //Process the message
}
catch (Exception e)
{
response = e.getCause().toString();
}
}
}
public class Listener implements Runnable
{
private DataInputStream reader = null;
private boolean keepListening;
private String serverMessage;
private Connection connection;
public Listener (DataInputStream inFromServer, Connection connection)
{
reader = inFromServer;
//Get the client connection's message transfer
keepListening = true;
this.connection = connection;
}
public void run()
{
while (keepListening)
{
try
{
if (reader.available() > 0)
{
byte[] readInData = new byte[reader.available()]; //Initialise the array
reader.read (readInData); //Read in the data
serverMessage = Utils.byteToString(readInData);
connection.reportMessage(serverMessage); //Report the message
}
}
catch (IOException e)
{
System.out.println("Error reading." + e.getLocalizedMessage().toString());
keepListening = false;
}
keepListening = connection.getKeepListening();
}
}
}
This works well for a time, then sometimes I receive an error which crashes the program.
When running in debug mode, I get a NullPointerException thrown on whatever is the first line of reportMessage() in the Connection class.
The program is suspended on whatever line is the first line, whether it is a System.out.println or a line of actual code.
And the error doesn't get caught by the try and catch. It crashes the program and there is no handling of the error even though it occurs in the try and catch.
This leads me to believe the error is not being thrown by anything in the reportMessage() method. If this is the case, then perhaps the error is being thrown in the Listener class .run().
However, I cannot see where any NullPointerException can be thrown from, as I have tried to make all the checks and when it is thrown, it is thrown when there are messages being sent.
The debugger says "An exception stack trace is not available".
The LogCat says:
08-21 10:35:57.894: E/AndroidRuntime(1118): FATAL EXCEPTION: Thread-12
08-21 10:35:57.894: E/AndroidRuntime(1118): java.lang.NullPointerException
08-21 10:35:57.894: E/AndroidRuntime(1118):atCom.que.wifiaudio.Connection.reportMessage(Connection.java:339)
08-21 10:35:57.894: E/AndroidRuntime(1118): at com.que.wifiaudio.Listener.reportIncomingMessage(Listener.java:93)
08-21 10:35:57.894: E/AndroidRuntime(1118): at com.que.wifiaudio.Listener.run(Listener.java:67)
08-21 10:35:57.894: E/AndroidRuntime(1118): at java.lang.Thread.run(Thread.java:1102)
Can anyone help me?
I need to know what is throwing the NullPointerException and how to stop it!
Turns out it was the
catch (Exception e)
{
response = e.getCause().toString();
}
The processData() method was throwing an exception which was being caught, but the Exception's cause was Null, which was throwing the error.

Categories

Resources