Skip to content
Advertisement

Android Studio Connect to Socket server

I have a server running in Java using Eclipse (Here the full code):

public class Main {

public static void main(String[]args) {
    
    // BBDD connection var
    Connection con = null;
    
    // Sockets
    ServerSocket server = null;
    try {
        server = new ServerSocket(5010);
    } catch (IOException e2) {System.out.println("Error at creating server, check if the port is in use");System.exit(-1);}
    
    /*** MySQL driver loading***/
    try {
        Class.forName("com.mysql.jdbc.Driver");
        System.out.println("MySQL driver is UP");
    } catch (ClassNotFoundException e1) {System.out.println("Error loading MySQL driver");}
    
    /*** Stablishing connection with the ddbb ***/
    try {
        con= (Connection) DriverManager.getConnection("jdbc:mysql://IP/Database", "username", "password");
        System.out.println("Connection stablished");
    } catch (SQLException e) {
        System.out.println("SQL ERROR");
        e.printStackTrace();
    }
    
    /*** Assigning thread for client ***/
    System.out.println("Listening for new requests...");
    while (true) {
        
        try {
            Socket clientSocket;
            clientSocket = server.accept();
            System.out.println("Connection stablished");
            
            DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
            DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream());
            
            ThreadForClient client = new ThreadForClient(con, clientSocket, dis, dos);

            Thread thread = new Thread(cliente);
            thread .start();
        } catch (IOException e) {System.out.println("Error making client socket");}
    }
}

class ThreadForClient implements Runnable {

Connection con;
Socket clientSocket;
DataInputStream dis;
DataOutputStream dos;

public ThreadForClient(Connection con, Socket s, DataInputStream dis, DataOutputStream dos) {
    this.con = con;
    this.clientSocket = s;
    this.dis = dis;
    this.dos = dos;
 }

@Override
public void run() {

    try {
        int opc = dis.readInt();
        switch (opc) {
            case 1:
                String email = dis.readUTF();
                Boolean result = existeUsuario(email);
                dos.writeBoolean(result);
                break;
            default: break;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public Boolean userExists(String email) throws SQLException { // 1
    
    email = email.toLowerCase();
    Statement stmt;
    stmt = con.createStatement();
    ResultSet rs=stmt.executeQuery("select * from users where email = '"+email+"'");
    boolean result = rs.first();
    return result;
}

}

As you can see, the client sends 2 values and receives 1, the first one is for the switch, which will indicate what to exceute, for now I just have on option (checking if email exists in the ddbb), the second value is the email as the code has already entered the switch.

The server is fully working and I already tested it with a Client Test project in Eclipse (It is what I want to do in Android Studio):

public static void main(String[] args) {
    
    Socket socket = null;
    try {
        socket = new Socket(HOST, PORT);
        System.out.println("Conection succesful");
        
        DataOutputStream dos;
        DataInputStream dis;
        
        dos = new DataOutputStream(socket.getOutputStream());
        dis = new DataInputStream(socket.getInputStream());
        

        dos.writeInt(1);
        dos.writeUTF("email@example.com");
        
        Boolean bool = dis.readBoolean();
        if (bool) {
            System.out.println("Email exists in the BBDD.");
        } else {
            System.out.println("Email does not exist in the BBDD.");
        }
        
        socket.close();
        
    } catch (Exception e) {System.out.println("Server connection failed");}
  
}

Now what I want to do is doing the same client in Android Studio so it can connect to the server.

I tried this:

public class SocketConnection {

UserExists ue;

public SocketConnection() throws IOException {
    connect();
}

public void connect() {
   
    ue = new UserExists();
    ue.execute();

}
}

class UserExists extends AsyncTask<Void, Void, Void> {

int PORT = 5010;
String HOST = "192.168.1.5";
private Socket socket;

private DataOutputStream dos;
private DataInputStream dis;

@Override
protected Void doInBackground(Void... voids) {
    try {
        socket = new Socket(HOST, PORT);
        dos = new DataOutputStream(socket.getOutputStream());
        dis = new DataInputStream(socket.getInputStream());
    } catch (Exception e) {
        System.out.println("Socket error");
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onPostExecute(Void result) {
    super.onPostExecute(result);
}
}

When I run it it does not give me any error but if I log the socket value at doInBackground’s bottom to see the socket value, it says it is null.

I also tried using Thread and Handle but I can’t get the result the server gives me back to the main thread.

Advertisement

Answer

I managed to resolve this. I just made a thread inside a “Connection” class in Android Studio.

Inside “Connection” I have some class-level variables, which I use with the thread (The thread can’t modify variables in the method the thread was created but it can read class-level variables) so the thread itself makes the connection with the socket server and saves the value taken to also a class-level variable.

In the main thread (in the same method that called the thread) I used a loop that looks at the thread status, if it has finished, reads the variable and applies it where I want.

Here the code:

public class Connection{

private String HOST = "83.xx.xx.xx";
private int PORT = 5010;

private Socket socket;

private DataOutputStream dos;
private DataInputStream dis;

boolean result;
String email;

public boolean userExists(String dev) throws InterruptedException { // true = exists, false = does not exist. dev is the email to search
    this.email = dev;
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                socket = new Socket(HOST, PORT);
                dos = new DataOutputStream(socket.getOutputStream());
                dis = new DataInputStream((socket.getInputStream()));
                dos.writeInt(1); // 1 = Sends the option for telling the server that we want to search a user
                dos.writeUTF(email); //Sends the email
                result = dis.readBoolean(); // Recieve if email exists or not
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("Couldn't connect to server");
            }
        }
    });
    thread.start();
    for (int c=0; c<25; c++){ //Wait for the thread to end
        if (thread.isAlive()) {
            //Thread hasn't finished yet...
            Thread.sleep(100);
        } else if (c == 24) {
            //This would be a timeout
            result = false;
        } else {
            //Thread has finished
            break;
        }
    }
    return result; // true in case server found the email, false in case it doesn't or in case of a timeout
}

I think another possibility could be making the thread just do the connection (and another one for closing it) and saving the socket as class-level variable, so you can send and receive from the main thread, I didn’t try it tho.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement