javaarraylistserversocketjansi

Comparing strings not working, and empty list not empty


I am working on a little Server - Client program. The code I have here runs in a different program as well and works fine, but for some reason in this program does not.

So when the user wants to login they type their Username and Password this message is then sent as "loginreq user:pass" to the server socket.

Although the Client clearly isn't the problem (I think) I will provide the code for you:

private static void loginreq(){
    String User = null;
    String Pass = null;
    try {
        User = bufferRead.readLine();
        WriteOut(ANSI_RESET+"Password: " + ANSI_GREEN);
        Pass = bufferRead.readLine();
        WriteOut(ANSI_RESET);
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    int serverPort = 6880;
      String ip = Server;
      String data = "loginreq " + User + ":" + Pass;
    try{ 
        Socket s = new Socket(ip, serverPort); 
        DataInputStream input = new DataInputStream( s.getInputStream()); 
      DataOutputStream output = new DataOutputStream( s.getOutputStream());
      if(s.isConnected()){
          //Step 1 send length
          System.out.println("Length"+ data.length());
          output.writeInt(data.length());
          //Step 2 send length
          System.out.println("Writing.......");
          output.writeBytes(data); // UTF is a string encoding

          //Step 1 read length
          int nb = input.readInt();
          byte[] digit = new byte[nb];
          //Step 2 read byte
          for(int i = 0; i < nb; i++){
            digit[i] = input.readByte();
          }
          String st = new String(digit);
      System.out.println("Received: "+ st);
    } else {
        WriteOut("Failed to connect to the server: "+Server+ "No Server");
    }
    }
    catch (UnknownHostException e){ 
        WriteOut("Sock:"+e.getMessage());
    }
    catch (EOFException e){
        WriteOut("EOF:"+e.getMessage()); 
    }
    catch (IOException e){
        WriteOut("IO:"+e.getMessage());
    }
}

The above gets the username and password and sends it as I explained before.

Then the Server does it's magic (or lack there of) The Server code:

//Step 1 read length
          int nb = input.readInt();
          byte[] digit = new byte[nb];
          //Step 2 read byte
           String st =null;
          for(int i = 0; i < nb; i++){
            digit[i] = input.readByte();

           st = new String(digit);
          }
          ServerOut("Recieved : " + ANSI_CYAN +
            clientSocket.getInetAddress() + ANSI_RESET + " - " + st);
            if (st.startsWith("loginreq ")){ //login attempt
                ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() +" Proccessing login request from: " + clientSocket.getInetAddress());
                try(BufferedReader br = new BufferedReader(new FileReader("users.txt"))) {
                    st = st.replaceFirst("loginreq ", "");
                    for(String line; (line = br.readLine()) != null; ) {
                        if(st.equals(line)){
                            String[] userDat = st.split(":");
                            boolean duplicate = false;
                            if(!connected.isEmpty()){
                            for(User u : connected){
                                if (u.getUsername().equals(userDat[0])){
                                    duplicate = true;
                                    break;
                                } else {

                                }
                            }
                            }
                            if (duplicate){
                                ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() +" User rejected (duplicate) " + userDat[0] + " : " + clientSocket.getInetAddress());
                                clientReturn("User was already logged in!");
                            } else {
                                User user = new User(clientSocket.getInetAddress().toString(), userDat[0], (int) time);
                                connected.add(user);
                                ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() + " User: '" + userDat[0] + "' logged in with ip: " + clientSocket.getInetAddress());
                                clientReturn("Login accepted!");
                            }
                            break;
                        }
                    }
                } catch (Exception ex){
                    clientReturn("Server ran into an error!");
                    ex.printStackTrace();
                }
            }

This reads the client input and if it starts with "loginreq ", then removes that and separates the string so that userDat[0] is the username and userDat[1] is the password. By this point it has already verified that the user exists. Then, if there are users connected (I've just started the server so there aren't any) it finds out if that same user is already logged in, which for some reason seems to return true. It then returns to the client that the user was already logged in. Not only is this a problem, but While the initial startup code using ServerOut prints to the console properly, now that it's in a new thread it seems to not print at all. I suspect this may be because I am using the Jansi console but IDK.

Sorry this was such a long post, but thanks for putting up with it!


Solution

  • The problem appears to be that the connected list contains entries when it should not contain any.

    You need to figure out how that has happened. Look at the code that creates the list object, and check that you have not prepopulated it with the wrong stuff. A list will not magically acquire entries out of thin air1. If it is non-empty, then your code has put the entries there ... somewhere, somehow.

    I would also add some logging to see what connected contains, and what userDat[0] is immediately before the "duplicate checking" code.

    Finally, since you mention that this code is multi-threaded:

    (I suspect that you aren't synchronizing properly. That would not directly explain the behavior you have described ... connected non-empty before anyone has tried to login ... but it is liable to cause other problems.)

    If this doesn't help, then you will need to provide an MCVE so that we can >>run<< your code to figure out what is actually going on here.


    1 - While it is theoretically possible, I would discount the possibility of bugs in the class libraries or the JVM.