Robert_Stark
Robert_Stark

Reputation: 31

socket - Android client - Java server PC gets stuck

Well, this is my second post and I'm going through such a big problem with socket communication TCP/IP, between android client and a java server application running on a PC.

What I try to do is send a string when I press a button from my client application to the server and then get an answer back to my client application as many times as I wish, this result is shown in a TextView of my client.

The problem occurs when I try to connect to the server with my client application, the connection is performed successfully, but when I press the button and send the data, the client application gets stuck and the only way to show a result is stopping the server application. Please, I need help! I'm new to Android. Thanks.

This is the simple server code:

import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ServerSocks {

private static ServerSocket myServer;
private static Socket myClient;
private static String msj_ToServer;

public static void main (String args[] ){

    try {

        System.out.println("Bienvenido:\n");

        System.out.println("Por favor ingresar el nº de puerto de comunicación: ");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String portNumber_str = in.readLine();
        int portNumber = Integer.parseInt(portNumber_str);
        myServer = new ServerSocket(portNumber);

            if(myServer.isBound() == true){

            System.out.println("Iniciando servidor en el puerto: "+portNumber); 

            } 

            else{

            System.err.println("[E R R O R] : No se pudo crear 'LISTEN SOCKET'");
            System.exit(0);

            }

            while(true){

            System.out.println("Esperando algún cliente TCP en el puerto ["+portNumber+"]...");
            myClient = myServer.accept();

            if (myClient.isConnected()) { // if2

            System.out.println("[D A T A] : El cliente ha sido aceptado IP-CLIENT\n"+""+ "IP Client address: "+myClient.getInetAddress());

            DataOutputStream outClient = new DataOutputStream(myClient.getOutputStream());

            DataInputStream inClient = new DataInputStream(myClient.getInputStream());
            msj_ToServer = inClient.readLine();
            System.out.println("Ha1 "+msj_ToServer);

            try{


            if(msj_ToServer.equalsIgnoreCase("D")) {
            System.out.println("HO "+msj_ToServer);
            outClient.writeBytes("ON");
            outClient.flush();
            break;              

            } 

            }catch(IOException e){
             e.printStackTrace();
             }

            if(msj_ToServer == "B" || msj_ToServer == "b"){

               System.out.println(msj_ToServer);
               outClient.writeUTF("OFF");
               outClient.flush();
               break;
               }

               if(msj_ToServer == "C" || msj_ToServer == "c"){
               System.out.println(msj_ToServer);
               outClient.writeUTF("xd");
               outClient.flush();
               break;
               }

               } // fin while inicio de lectura  */

               } // fin msj1

              } // fin while prueba 3
              }// fin if2


              } // fin while (true) superior

           } catch (IOException ex) {
                 Logger.getLogger(ServerSocket.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }

    }// fin main 

} // fin clase ServerSocks

This is part of the Main.java of my Android client application (I'm probing with the button ("status" button) that is sending a "D" string to the server and the server sends back an "ON" as an answer).

public class MainActivity extends Activity implements OnClickListener {

private Button ledOnButton;
private Button ledOffButton;
static ToggleButton toggleButton; 
static EditText statusEditText;
private Button status;
static TextView prueba; 

static Socket clientSocket; 
static String data;

static String dato;

static PrintStream os;
static DataInputStream is;
static DataInputStream inputLine;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }

    ledOnButton = (Button) findViewById(R.id.ledOnButton);
    ledOnButton.setOnClickListener(this);

    ledOffButton = (Button) findViewById(R.id.ledOffButton);
    ledOffButton.setOnClickListener(this);

    toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
    toggleButton.setOnClickListener(this);

    status = (Button) findViewById(R.id.statusButton);
    status.setOnClickListener(this);

    statusEditText = (EditText) findViewById(R.id.statusEditText);

    // prueba con textView

    prueba = (TextView) findViewById(R.id.textView_Prueba);

} // fin OnCreate

@Override

public void onClick(View arg0) {

    AsyncAction object = new AsyncAction();
    final String salida_dato;


switch (arg0.getId()) {

    case R.id.toggleButton:


        if (toggleButton.isChecked()) {

            object.conexion_socket();


        }

        if (!toggleButton.isChecked()) {

            object.desconexion_socket();

        }


        break;

    case R.id.ledOnButton:


        if ((MainActivity.toggleButton.isChecked())) {

            object.ledOnButton();
        }

        break;

    case R.id.ledOffButton:

        if ((toggleButton.isChecked())) {

            object.ledOffButton();
        }

        break;

    case R.id.statusButton:

here i try to send a "D" String to the server

        if ((toggleButton.isChecked())) {


            if (clientSocket != null && os != null && is != null) {

                try {

                    final String responseLine;
                    //    String data = "D";
                    //os.write(data.getBytes());
                 os.println("D");


                    while ((responseLine = is.readLine()) != null) {
                        System.out.println(responseLine);


                        runOnUiThread(new Runnable() {
                            public void run() {
                                MainActivity.prueba.setText(responseLine);
                                os.flush();

                            }
                        });

                        break;


                    }

                    os.close();
                    is.close();
                    clientSocket.close();

                } //fin try

                catch (UnknownHostException e) {
                    System.err.println("Trying to connect to unknown host: " + e);
                } catch (IOException e) {
                    System.err.println("IOException:  " + e);
                }

and here the connection is running in background with asynchTasks (i think so)

    @Override
    protected String doInBackground(Void... args) {

        conexion_socket();

        ...


    }//fin doInBackground

and here is the connection method that i used to create the socket connection

public void conexion_socket(){

        try {

            MainActivity.clientSocket = new Socket("192.168.2.80", 30000);

            try {

                MainActivity.os = new PrintStream(MainActivity.clientSocket.getOutputStream());
                MainActivity.is = new DataInputStream(MainActivity.clientSocket.getInputStream());
                MainActivity.inputLine = new DataInputStream(new BufferedInputStream(System.in));

            } // fin try

            catch (IOException e){

                System.err.println("algo anda al con los i/o ...");

            } // fin catch




        } catch (IOException e) {
            e.printStackTrace();
        }
        if (MainActivity.clientSocket.isConnected()) {
            MainActivity.statusEditText.setText("OK connection");
        }
    }

please if anyone could give a way to do this communication i would appreciate very much!

Upvotes: 3

Views: 105

Answers (1)

user207421
user207421

Reputation: 310860

if(myServer.isBound() == true){

This cannot possibly be false at this point. Remove test and the else block. You constructed the ServerSocket with a port number => it is bound.

        else{
        System.err.println("[E R R O R] : No se pudo crear 'LISTEN SOCKET'");
        System.exit(0);
        }

Unreachable. Remove.

        while(true){
        System.out.println("Esperando algún cliente TCP en el puerto ["+portNumber+"]...");
        myClient = myServer.accept();
        if (myClient.isConnected()) { // if2

Once again this cannot possibly be false. You accepted the socket => it is connected. Don't write futile tests.

        System.out.println("[D A T A] : El cliente ha sido aceptado IP-CLIENT\n"+""+ "IP Client address: "+myClient.getInetAddress());
        DataOutputStream outClient = new DataOutputStream(myClient.getOutputStream());
        DataInputStream inClient = new DataInputStream(myClient.getInputStream());
        msj_ToServer = inClient.readLine();
        System.out.println("Ha1 "+msj_ToServer);
        try{

        if(msj_ToServer.equalsIgnoreCase("D")) {
        System.out.println("HO "+msj_ToServer);
        outClient.writeBytes("ON");

Here you are writing bytes but no line terminator. The corresponding code in the client is using readLine(), so it will block forever. Add a line terminator to this string.

        outClient.flush();

Redundant. Remove. DataOutputStream is not buffered, and neither is Socket.getOutputStream(), so flushing either of them does nothing.

        }catch(IOException e){
         e.printStackTrace();
         }

        if(msj_ToServer == "B" || msj_ToServer == "b"){

           System.out.println(msj_ToServer);
           outClient.writeUTF("OFF");

Make up your mind. Are you writing bytes, or lines, or the special format used by writeUTF()? The corresponding code in the client uses readLine(). I suggest you standardize on writing lines for reading by readLine(), or writeUTF()/readUTF(). You cannot mix them.

           outClient.flush();

See above. Remove.

           if(msj_ToServer == "C" || msj_ToServer == "c"){
           System.out.println(msj_ToServer);
           outClient.writeUTF("xd");

See above.

           outClient.flush();

See above.

        MainActivity.clientSocket = new Socket("192.168.2.80", 30000);

        try {

            MainActivity.os = new PrintStream(MainActivity.clientSocket.getOutputStream());
            MainActivity.is = new DataInputStream(MainActivity.clientSocket.getInputStream());
            MainActivity.inputLine = new DataInputStream(new BufferedInputStream(System.in));

        } // fin try
        catch (IOException e){
            System.err.println("algo anda al con los i/o ...");
        } // fin catch

There is no reason to put these lines of code inside a try block. You're already inside one.

    if (MainActivity.clientSocket.isConnected()) {

Yet again this test cannot possibly be false at this point. If the socket was constructed, it is connected.

It can however be null, due to your incorrectly structured exception handling. The block that follows this should be inside the prior enclosing try block.

In general you should get rid of all the interior try/catch blocks. Code that depends on the success of code in a prior try block should be inside that try block.

Upvotes: 2

Related Questions