0

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.

2 Answers2

0

According to RFC 1918, addresses in the 192.168.0.0-192.168.255.255 range are private. Such addresses can be used internally by any network so they're often used inside an organization. They cannot be used on the Internet since they aren't unique. Why my ip address starts with 192.?

I think that your local network is somehow preventing that connection. But without further details nobody can actually tell as far I know.

If you are running everything on the same computer you may want to take a look at "loopback" address. Usually 127.0.0.1 , that should loop back to your machine.

If you want to run a full server you may need to dig more into networking and want to understand how networks function.

TyjameTheNeko
  • 116
  • 1
  • 9
  • I just tryied now with my public IP opening the ports and changing the AsyncTask host direction to: 83.**.**.**:5010 but it isn't working, it is not executing the method and still leaving the socket server as null. –  May 24 '21 at 07:00
  • Where did you get 83.xx.xx.xx:5010 from ? – TyjameTheNeko May 25 '21 at 11:15
  • It is my public IP, that's why I replaced it with 'x'. –  May 25 '21 at 12:29
  • Also now that it works, I tried using my local IP address (192.168.1.5) and also works! it wasn't an IP issue. You can use 192.x.x.x, 127.0.0.1 (localhost) and also public one. You can find yours in https://whatismyipaddress.com, just don't forget to open the right ports in your router! –  May 25 '21 at 13:10
0

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.