Android socket app crash - android

I want my app to connect to a server. I only want the client.
protected void onCreate(Bundle savedInstanceState) {
//...
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
} catch (UnknownHostException e1) {
//...
} catch (IOException e1) {
//...
}
}
But the application just crashes. I started this activity by pressing a button.
Do you know what the problem could be?

You need to perform all your blocking processes in a Thread, and release the main UI Thread, for example:
protected void onCreate(Bundle savedInstanceState) {
//...
new Thread(){
public run(){
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
} catch (UnknownHostException e1) {
//...
} catch (IOException e1) {
//...
}
}
}.start();
}

Related

How to check if Socket is established before changing activity

Whenever I run my code, I am not being redirected to the next activity when my socket connection is established, instead it moves to else part and shows the fail to connect toast. I know it is connecting correctly, from the output of my other device. Is there something wrong with my IF condition? Or the "Socket != null" was incorrectly used?
public void connecttoserver(View view){
final TextView txtenterlumens;
txtenterlumens = (TextView) findViewById(R.id.txtenterlumens);
if(!txtenterlumens.getText().toString().equals("")) {
enterlumens = Integer.parseInt(txtenterlumens.getText().toString());
new Thread(new ClientThread()).start();
if(socket!=null){
Intent goToNextActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(goToNextActivity);
}
else {
Toast.makeText(LoginActivity.this, "Fail to connect!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
else{
Toast.makeText(LoginActivity.this, "Please enter correct Lumens!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
This is my socket creation code:
public class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
setSocket(socket);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
You are creating socket in ClientThread but verifying it in another class, but you dont retrieve it. Add this method to ClientThread:
public boolean isConnected(){
return socket !=null
}
and then slightly edit your connecttoserver to this :
ClientThread ct = new new ClientThread();
new Thread(ct).start();
if(ct.isConnected(){...}
You init socket on another thread, so the result can not get immediately. Let do something like below. I haven't test this code yet.
public void connecttoserver(View view){
final TextView txtenterlumens;
txtenterlumens = (TextView) findViewById(R.id.txtenterlumens);
if(!txtenterlumens.getText().toString().equals("")) {
enterlumens = Integer.parseInt(txtenterlumens.getText().toString());
new Thread(new ClientThread(new EstablishListener() {
public void onEstablishCompleted(Socket socket) {
setSocket(socket);
if(socket!=null){
Intent goToNextActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(goToNextActivity);
}
else {
Toast.makeText(LoginActivity.this, "Fail to connect!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
})).start();
}
else{
Toast.makeText(LoginActivity.this, "Please enter correct Lumens!", Toast.LENGTH_LONG).show();
txtenterlumens.setText("");
}
}
public class ClientThread implements Runnable {
EstablishListener mListener = null;
public ClientThread(EstablishListener listner) {
mListener = listner;
}
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
mListener.onEstablishCompleted(socket);
} catch (UnknownHostException e1) {
mListener.onEstablishCompleted(null);
e1.printStackTrace();
} catch (IOException e1) {
mListener.onEstablishCompleted(null);
e1.printStackTrace();
}
}
}
// Create function interface for callback
public interface EstablishListener {
void onEstablishCompleted(Socket socket);
}
Thanks everyone for your help. I decided it would be easiest if I do the check for socket connection and activity changing in the ClientThread instead.
public class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
setSocket(socket);
if(socket!=null){
Intent goToNextActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(goToNextActivity);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}

Android Socket: Send Data Repeatedly with a Fixed Time Interval

I have a code that sends data on click. However, I want to send data repeatedly with a fixed time interval.
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
any help would be appreciated.
Create a new thread with a while loop and a Thread.sleep() call.
This post has all the code you need:
How to run a Runnable thread in Android?

Thread in Service causes ANR

I'm trying to respond to multicast DatagramPackets on my phone. This is the part of the code that keeps causing the ANR:
private void multicastLoop() {
String res = Build.FINGERPRINT + "\n";
final InetAddress group;
final MulticastSocket socket;
final DatagramPacket response;
try {
group = InetAddress.getByName("239.255.255.127");
socket = new MulticastSocket(port);
socket.setLoopbackMode(true);
socket.setSoTimeout(1000);
socket.joinGroup(group);
response = new DatagramPacket(res.getBytes(), res.length(), group, port);
} catch (IOException e) {
e.printStackTrace();
return;
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning) {
try {
byte[] data = new byte[1024];
DatagramPacket dm = new DatagramPacket(data, data.length);
socket.receive(dm);
if (Arrays.equals(dm.getData(), "someone there".getBytes())) {
socket.send(response);
}
} catch (SocketTimeoutException e) {
continue;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.leaveGroup(group);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.run();
}
The method multicastLoop is called in the onCreate of the Service, after setting isRunning = true; Why does this Thread cause an ANR error? The TCP-Server-Thread is running without problems (while (isRunning) {...})
You need to call t.start(); instead of t.run();
t.run() will just execute the Runnable on the current thread (the UI) which causes the ANR.

closing client let the server crash

I've a simple client and server on android. Everything works fine except when I close the client app then the server stops working the app closes.
I think it's about not closing the socket. But when I close the socket in the client the server still stops working.
I'm running a thread on the server. This is my server code:
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
private boolean feedback = false;
public updateUIThread(String str) {
msg = str;
}
#Override
public void run() {
parseCommand();
if(feedback)
{
textFeedback.setText(msg);
feedback = false;
}
else
{
textTv.setText(msg);
}
}
if(msg != null)
parseCommand();
and in
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
if(read == null)
{
clientSocket.close();
Log.d("Test","SOCKET CLOSED");
return;
}
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}

How to stop Socket to send a lot of useless data when closed?

I use these codes for communicating between devices. If i close or kill the client app, the server app gets thousands of useless data. The textView in the server side is full of this: Client says: null. If i close the client twice, the server stops with StackOverFlowError. How can i make the code to dont send this null values when the app stops? Or can i filter the server side to do nothing when getting this data?
Client:
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Server:
public class Server extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 1599;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
I think you should use a delimiter character, to tell the Server your Client it's about to die. Add that character of code in onPause method of your Android Activity/Fragment.
Then in your Server, just get the String or byte and compare it against your Delimiter String/Character and stop the Server listening for the Connection.
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is here. You aren't checking the result of readLine() for null. If it returns null, the peer has closed the connection and you should do likewise, and exit this loop. You can probably get rid of the isInterrupted() test as well.
Also, if you get any IOException other that a read timeout when reading from a socket, the connection is dead and you must close the socket and exit your loop.

Categories

Resources