[SOLUCIONADO] ¿Cómo recibir y mandar datos desde Android a la PC c/programación?

Iniciado por proxy_lainux, Enero 02, 2015, 09:37:12 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

hola

Estoy tratando de crear un cliente-servidor entre un celular android y linux en PC, ya logré hacer la conexión, puedo mandar y recibir datos o en este caso, "cadenas de texto", tal vez estoy muy acostumbrado a C, pero como recordaran, con una conexión ya realizada se puede empezar a comunicar los sockets.

Bueno, ya logre esa comunicación, pero no se si funcione de la misma manera con Java, hasta el momento hago la conexión y mando un "hola" de android a la PC, y después mando alguna frase de la PC a android, pero aquí viene mi problema.

Al principio había dejado un botón y un textview para ver si se estaba realizando la conexión y la información se mandaba correctamente, y todo va bien, oprimo el botón para mandar un string desde android a la PC y después puedo volver a recibir otra cadena de caracteres desde la compu hacia android, etc, el clásico recv y send.

Pero como mencioné, tengo que oprimir un botón para poder mandar datos constantemente desde android a la PC y asi lograr mandar datos desde la PC a android nuevamente, y me gustaría poder mandar y recibir datos sin tener que oprimir nada en el celular.

Por ejemplo, me gustaría que cuando la aplicación en andriod se inicie, me mande una frase de "conexion aceptada", después yo mandar un frase de "hola", y android me mande otra cosa y así continuamente hasta que se termine la conexión. Para eso necesito saber como mantener la conexión activa y android reciba y mande información sin oprimir algo.

Traté de quitar el listener del botón y poner el socket en onCreate directamente, pero se detiene la aplicación, lo que quiere decir que así no funciona, ¿alguien me podría decir como realizar esa función, mantener la conexión activa y poder interactuar automáticamente con android?

Les dejo el código que encontré, lo he estado estudiando y modificando varias cosas para entender las cosas. A ver si me pueden explicar como realizar lo que necesito o como podría hacerlo de otra manera

Código: java
package com.clint;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

EditText textOut;
TextView textIn;

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

textOut = (EditText)findViewById(R.id.textout);
     Button buttonSend = (Button)findViewById(R.id.send);
     textIn = (TextView)findViewById(R.id.textin);
     buttonSend.setOnClickListener(buttonSendOnClickListener);
}

Button.OnClickListener buttonSendOnClickListener = new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;

try {
  socket = new Socket("192.168.0.17", 8888);
  dataOutputStream = new DataOutputStream(socket.getOutputStream());
  dataInputStream = new DataInputStream(socket.getInputStream());
  dataOutputStream.writeUTF("hola");
  textIn.setText(dataInputStream.readUTF());
} catch (UnknownHostException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}
finally{
  if (socket != null){
   try {
    socket.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  if (dataOutputStream != null){
   try {
    dataOutputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

  if (dataInputStream != null){
   try {
    dataInputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
}
}};
}

Lo primero que haría es crear un sistema cliente-servidor. En el servidor creas un socket que se quede a la espera del cliente. Cuando el cliente se conecte creas un thread para esa comunicación y, por medio de un bucle la mantenes hasta que un evento determinado lo finalice.

Saludos!
WhiZ


pues la conexion ya la tengo, la hago mediante un socket en java en la consola de linux, y en android la aplicación ya se establece y puedo mantener el intercambio de datos, lo que no entiendo es como realizar eso de forma automatica, me imagino que es como dices con algun hilo, pero no entiendo como.

pondré un ejemplo en C sobre lo que busco

en código se utiliza un ciclo en este caso un while en el cliente y servidor

Código: c
whie(1){

send(socket, "frase", tamaño, 0);

recv(socket, buffer, espacio, 0);

printf("%s", buffer);

}


ahora uno del servidor

Código: c
while(1){

recv(socket, buffer, espacio, 0);

if(strcmp(buffer, "whoami"){

send(socket, "android", tamaño,0);
}

}



Esto que escribí es muy tonto, así que no lo traten de decifrar o arreglar jeje.

pero es un ejemplo de lo que quisiera hacer, decirle desde linux un comando o funcion a realizar, android al recibirlo haga lo que le pido, y mande el resultado de nuevo a linux.

Como pueden ver en el código de android, puedo hacerlo, siempre y cuando oprima un boton, y quisiera dejarlo sin eso... ¿como lo harían?

Acá te dejo un simple sistema cliente-servidor.

SERVER
Código: java
/* Server */
import java.net.*;
import java.io.*;

class Server {
    public static void main(String[] args) {
        System.out.println(" [*] Running server...");
        ServerSocket server;
        int port = 2236;

        try {
            server = new ServerSocket(port);
            System.out.println(" [+] OK");

            System.out.println(" [*] Waiting for clients on port " + server.getLocalPort());
            Socket sock = server.accept();
            System.out.println(" [+] New client: " + sock.getRemoteSocketAddress());

            DataInputStream input = new DataInputStream(sock.getInputStream());
            System.out.println(" [*] Receiving data..." + input.readUTF());
            System.out.println(" [+] OK");

            DataOutputStream output = new DataOutputStream(sock.getOutputStream());
            System.out.println(" [*] Sending data...");
            output.writeUTF("Visit and join us at http://underc0de.org ;)");
            System.out.println(" [+] OK");

            sock.close();
        }
        catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}


CLIENT
Código: java
/* Client */

import java.net.*;
import java.io.*;

class Client {
    public static void main(String[] args) {
        String server = "127.0.0.1";
        int port = 2236;
        System.out.println(" [*] Connecting to the server [" + server + ":" + port + "]");

        try {
            Socket client = new Socket(server, port);
            System.out.println(" [+] OK");

            DataOutputStream output = new DataOutputStream(client.getOutputStream());
            System.out.println(" [*] Sending data...");
            output.writeUTF("Hello!");
            System.out.println(" [+] OK");

            DataInputStream input = new DataInputStream(client.getInputStream());
            System.out.println(" [*] Receiving data..." + input.readUTF());
            System.out.println(" [+] OK");

            client.close();
        }
        catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}


Con esto ya tenés un servidor que espera, automáticamente (me refiero, sin botones o cualquier otro evento), una conexión entrante.
En un rato subo el código con el bucle que te comentaba antes para lograr una interacción más dinámica.

Espero que esto te sirva de base para continuar.

Saludos!
WhiZ




EDITO: Ahora sí. Esta sería una versión más avanzada, con un bucle en el server que espera conexiones entrantes. Una vez iniciada una nueva conexión, se la pasa a la clase ThreadServerHandler quién se encarga del resto. El cliente sigue igual.

SERVER
Código: java
/* Server */
import java.net.*;
import java.io.*;

class Server {
    public static void main(String[] args) {
        System.out.println(" [*] Running server...");
        ServerSocket server;
        int port = 2236;

        try {
            server = new ServerSocket(port);
            System.out.println(" [+] OK");

            while (true) {
                System.out.println(" [*] Waiting for clients on port " + server.getLocalPort());
                Socket sock = server.accept();

                Thread t = new ThreadServerHandler(sock);
                t.start();
            }

        } catch(SocketTimeoutException e) {
            System.out.println(" [!] Error: " + e);

        } catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}

class ThreadServerHandler extends Thread {
    private Socket sock = null;

    public ThreadServerHandler(Socket sock) {
        super("ThreadServerHandler");
        this.sock = sock;
    }

    public void run() {
        try {
            System.out.println(" [+] New client: " + sock.getRemoteSocketAddress());

            DataInputStream input = new DataInputStream(sock.getInputStream());
            System.out.println(" [*] Receiving data..." + input.readUTF());
            System.out.println(" [+] OK");

            DataOutputStream output = new DataOutputStream(sock.getOutputStream());
            System.out.println(" [*] Sending data...");
            output.writeUTF("Visit and join us at http://underc0de.org ;)");
            System.out.println(" [+] OK");

            sock.close();
        }
        catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}


Lo que tendrías que hacer ahora es modificar la clase ThreadServerHandler: poner un bucle que reciba y envíe información hasta que por medio de un evento determinado, finalice la conexión. Los cambios que hagas en dicha clase deberán acompañarse de las modificaciones respectivas en el cliente.

Espero que te sirva!

Saludos!
WhiZ

P.D.: Seguro que más tarde subo un nuevo código, así practico un poco de java jeje


Gracias, ya estoy comprendiendo... llevo poco tiempo en Java así que tendré que revisarlo para practicar, porque yo había hecho un cliente pero bastante desordenado jeje

Muchas gracias nuevamente, ya solo falta ver como lo integro en Android para hacer lo que mencionas, estuve googleando sobre los hilos y con tu ejemplo ya comprendí sobre Run, ya solo me falta leer bastante la documentación de oracle porque si me falta por aprender cosas de Java.

Ojala sigas subiendo más cosas, les entiendo mejor jeje

Saludos.

Bueno, acá te dejo una de las últimas versiones (mis conocimientos en java no dan para mucho más jeje).

SERVER
Código: java
/* Server */
import java.net.*;
import java.io.*;

class Server {
    public static void main(String[] args) {
        System.out.println(" [*] Running server...");
        ServerSocket server;
        int port = 2236;

        try {
            server = new ServerSocket(port);
            System.out.println(" [+] OK");
            System.out.println(" [*] Waiting for clients on port " + server.getLocalPort());

            while (true) {
                Socket sock = server.accept();

                Thread t = new ThreadServerHandler(sock);
                t.start();
            }

        } catch(SocketTimeoutException e) {
            System.out.println(" [!] Error: " + e);

        } catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}

class ThreadServerHandler extends Thread {
    private Socket sock = null;

    public ThreadServerHandler(Socket sock) {
        super("ThreadServerHandler");
        this.sock = sock;
    }

    public void run() {
        try {
            System.out.println("\n [+] New client: " + sock.getRemoteSocketAddress());

            while (true) {
               
                // Receiving data
                DataInputStream input = new DataInputStream(sock.getInputStream());
                String data = input.readUTF();

                System.out.println("\n [*] Receiving data..." + data);
                System.out.println(" [+] OK");

                // Sending data

                DataOutputStream output = new DataOutputStream(sock.getOutputStream());
                System.out.println(" [*] Sending data..." + data);
                output.writeUTF(data);
                System.out.println(" [+] OK");

                // Exit
                if (data.equals("exit")) {
                    System.out.println("\n [*] Closing connection to host " + sock.getRemoteSocketAddress());
                    sock.close();
                    break;
                }
            }
        }
        catch (IOException e) {
            System.out.println(" [!] Error: the connection with host " +
                sock.getRemoteSocketAddress() + " has been lost");
        }
    }
}


CLIENT
Código: java
/* Client */

import java.net.*;
import java.io.*;
import java.util.Scanner;

class Client {
    public static void main(String[] args) {
        String server = "127.0.0.1";
        int port = 2236;
        System.out.println(" [*] Connecting to the server [" + server + ":" + port + "]");

        try {
            Socket client = new Socket(server, port);
            System.out.println(" [+] OK");

            while (true) {
                // Input
                System.out.print("\n [?] Command: ");
                Scanner scan = new Scanner(System.in);
                String data = scan.nextLine();
                data.trim();

                // Sending data
                System.out.println(" [*] Sending data..." + data);
                DataOutputStream output = new DataOutputStream(client.getOutputStream());
                output.writeUTF(data);
                System.out.println(" [+] OK");

                // Receiving data
                DataInputStream input = new DataInputStream(client.getInputStream());
                data = input.readUTF();
                System.out.println(" [*] Receiving data..." + data);
                System.out.println(" [+] OK");

                // Exit
                if (data.equals("exit")) {
                    System.out.println("\n [*] Closing connection...");
                    client.close();
                    break;
                }
            }
        }
        catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}


Faltaría que modifiques el servidor para que trate a cada dato recibido como un comando, es decir, que lo envíe como comando al sistema y, finalmente, devuelva la respuesta al cliente (seguro que en un rato lo hago). Con eso ya tendrías una remote shell. Si querés obtener algo mejor y más actualizado, tenés que invertir los roles, es decir, hacer que el cliente reciba los comandos, los ejecute en el sistema y envíe de vuelta la respuesta al servidor (con eso lograrías una reverse shell ;) ).

Saludos!
WhiZ



Bueno, última edición. Acá te dejo la remote shell. Con este código podrás ejecutar comandos de forma remota. Sólo te queda hacerlo reverse  :)

SERVER
Código: java
/* Server */
import java.net.*;
import java.io.*;

class Server {
    public static void main(String[] args) {
        System.out.println(" [*] Running server...");
        ServerSocket server;
        int port = 2236;

        try {
            server = new ServerSocket(port);
            System.out.println(" [+] OK");
            System.out.println(" [*] Waiting for clients on port " + server.getLocalPort());

            while (true) {
                Socket sock = server.accept();

                Thread t = new ThreadServerHandler(sock);
                t.start();
            }

        } catch(SocketTimeoutException e) {
            System.out.println(" [!] Error: " + e);

        } catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}

class ThreadServerHandler extends Thread {
    private Socket sock = null;

    public ThreadServerHandler(Socket sock) {
        super("ThreadServerHandler");
        this.sock = sock;
    }

    public void run() {
        try {
            System.out.println("\n [+] New client: " + sock.getRemoteSocketAddress());

            while (true) {
               
                // Receiving data
                DataInputStream input = new DataInputStream(sock.getInputStream());
                String data = input.readUTF();

                System.out.println("\n [*] Receiving data from " +
                    sock.getRemoteSocketAddress() + "..." + data);
                System.out.println(" [+] OK");

                // Exit
                if (data.equals("exit")) {
                    System.out.println("\n [*] Closing connection to host " + sock.getRemoteSocketAddress());
                    DataOutputStream output = new DataOutputStream(sock.getOutputStream());
                    output.writeUTF(data);
                    sock.close();
                    break;
                }

                // Running the command
                String stdout = runCmd(data);

                // Sending data

                DataOutputStream output = new DataOutputStream(sock.getOutputStream());
                System.out.println(" [*] Sending data to " +
                sock.getRemoteSocketAddress() + "...");
                output.writeUTF(stdout);
                System.out.println(" [+] OK");

            }

        } catch (IOException e) {
            System.out.println(" [!] Error: the connection with host " +
                sock.getRemoteSocketAddress() + " has been lost");
        }
    }

    public String runCmd(String cmd) {
        try {
            String line = null;
            StringBuilder builder = new StringBuilder();
            builder.append("\n\n");

            Process p = Runtime.getRuntime().exec(cmd);
            p.waitFor();
         
            BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));

            while ((line = stdout.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty("line.separator"));
            }

            return builder.toString();

        } catch (IOException e) {
            System.out.println(" [!] Error: " + e);
            return "";

        } catch (InterruptedException e) {
            System.out.println(" [!] Keyboard Interrupt");
            return "";
        }
    }
}


CLIENT
Código: java
/* Client */

import java.net.*;
import java.io.*;
import java.util.Scanner;

class Client {
    public static void main(String[] args) {
        String server = "127.0.0.1";
        int port = 2236;
        System.out.println(" [*] Connecting to the server [" + server + ":" + port + "]");

        try {
            Socket client = new Socket(server, port);
            System.out.println(" [+] OK");

            while (true) {
                // Input
                System.out.print("\n [?] Command: ");
                Scanner scan = new Scanner(System.in);
                String data = scan.nextLine();
                data.trim();

                // Sending data
                System.out.println(" [*] Sending data..." + data);
                DataOutputStream output = new DataOutputStream(client.getOutputStream());
                output.writeUTF(data);
                System.out.println(" [+] OK");

                // Receiving data
                System.out.print(" [*] Receiving data...");
                DataInputStream input = new DataInputStream(client.getInputStream());
                data = input.readUTF();
                System.out.println(data);
                System.out.println(" [+] OK");

                // Exit
                if (data.equals("exit")) {
                    System.out.println("\n [*] Closing connection...");
                    client.close();
                    break;
                }
            }
        }
        catch (IOException e) {
            System.out.println(" [!] Error: " + e);
        }
    }
}


Espero que te sirva y que puedas llevar a cabo con éxito tu proyecto.

Saludos!
WhiZ