2014-11-26 3 views
0

У меня есть чат-программа. Проблема в том, что я пытаюсь запретить имена обманов. По сути, всякий раз, когда на сервер отправляется запрос на изменение имени, он проверяется на список имен, которые в настоящее время используются, и если он уже принят, человек добавляется в мой (не разрешается публиковать сообщения) и отправляется сообщение что им нужно изменить свое имя.Почему это сообщение отправляется неверному клиенту? (Deduping)

Я прокомментировал дерьмо из кода, так как есть много, поэтому вы можете легко понять это.

Проблема в том, что неверный человек отправляется сообщение о том, что имя уже используется! Я провел последние 8 часов, пытаясь найти его, и это чертовски сводит меня с ума!

Код на стороне сервера длинный; Я отправлю соответствующие биты, и любые другие будут предоставлены по запросу. Я также свяжусь с полной программой. (Не источник, JAR.)

JAR: https://www.mediafire.com/?4t2shjdjf7blpg2

//...Irrelevant bits ommitted...// 
public class Server 
{ 
    // The server object reference 
    static Server server; 

    // Declarations: 
    private ArrayList<ObjectOutputStream> clientOutputStreams; // out streams 
    private ArrayList<String> takenNames = new ArrayList<>(); // taken names 
    private InetAddress ip; 
    private final int serverPort; // the port the server is running on 
    private static ObjectOutputStream changer; // the last person to change names 
    private ArrayList<ObjectOutputStream> shitList = new ArrayList<>(); 

    private HashMap <InetAddress, ObjectOutputStream> ipMap = 
      new HashMap<>(); // <ip, outputstream> 

//...Irrelevant bits ommited...// 

// Don't mind this non-indentation, it is supposed to be. 
public void tellEveryone(Message message, InetAddress senderIP) 
{ 
    // First check some special conditions.. 
    if(message.getType() == Message.TYPE.IN_USE) 
    { 
     try 
     { 
      changer.writeObject(message); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    // If someone is on my shitlist, 
    if(shitList.contains(ipMap.get(senderIP))) 
    { 
     // Warn them of their sins... 
     Message nopeMessage = new Message(Message.TYPE.SERVER, 
      "You may not send any messages until you change your name!", 
       "Server"); 
     try 
     { 
      ipMap.get(senderIP).writeObject(nopeMessage); 
     } 
     catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    else 
    { 
     // Send message normally to everyone... 
     // Sync, just to be safe 
     synchronized(clientOutputStreams) 
     { 
      for(ObjectOutputStream oo : clientOutputStreams) // while more clients... 
      { 
       try 
       { 
        oo.writeObject(message); 
        oo.flush(); 
       } 

       catch(IOException e) 
       { 
        System.out.println("IOException caught during tellEveryone()"); 
        e.printStackTrace(); 
       } 
      } 
     } 
     System.out.println(getTimeStamp() + ": Message Sent by:". 
       concat(" " + senderIP + "/ " + message.getSenderName())); 
    } 
} 

Обработчик сервера внутренний класс ...

public class ServerHandler implements Runnable 
    { 
     @Override 
     public void run() 
     { 
      // Create a list of client out streams to send stuff... 
      clientOutputStreams = new ArrayList<>(); 
      try // To establish a connection with clients 
      { 
       // Create server socket... 
       ServerSocket serverSocket = new ServerSocket(serverPort); 
       while(true) // Will always run! Blocks! 
       { 
        // Assign a client socket to any new socket connections... 
        // (The var used here is temp, but will be passed off soon.) 
        Socket clientSocket = serverSocket.accept(); 
        // Get's the ip of the client that connected... 
        ip = clientSocket.getInetAddress(); 
        System.out.println(ip + " " + "connected."); 
        // Create ooStream to send messages to client... 
        ObjectOutputStream ooStream = 
          new ObjectOutputStream(
            clientSocket.getOutputStream()); 
        // Add the client oo stream to the list of outputs... 
        clientOutputStreams.add(ooStream); 
        // Add user IP data to map of ip's 
        ipMap.putIfAbsent(ip, ooStream); 
        // Create new thread to run inner class ClientHandler... 
        Thread t = new Thread(new ClientHandler(clientSocket)); 
        // Running the thread makes it safe to overwrite the... 
        // ...clientsocket variable. 
        t.start(); 
       } 
      } 
      catch (IOException e) 
      { 
       System.out.println("Exception in server.run()"); 
       // TODO: Revise 
       e.printStackTrace(); 
      } 
     } 
    } 

Обработчик клиента внутренний класс

public class ClientHandler implements Runnable 
{ 
    private ObjectInputStream oInStream; // The client's input stream. 
    private Socket socket; // Socket to the client 

    public ClientHandler(Socket clientSocket) 
    { 
     try // to create an input stream... 
     { 
      socket = clientSocket; // <-- The one passed in to the method 
      // Potential error from previous version... REMOVE WHEN TESTED 
      oInStream = new ObjectInputStream(socket.getInputStream()); 
     } 
     catch(IOException e) 
     { 
      System.out.println("Error establishing input stream"); 
     } 
    } 

    @Override 
    public void run() 
    { 
     Message message; 

     try // To process incoming messages... 
     { 
      while(socket.isClosed() == false) // If the socket is open... 
      { 
       // While there are more messages... 
       // Also assigns to the message var. 
       while((message = (Message)oInStream.readObject()) != null) 
       { 
        // Passes on the message and sender info. 
        if(message.getType() == Message.TYPE.NAME_REQUEST) 
        { 
         changer = ipMap.get(socket.getInetAddress()); 
         System.out.println(socket.getInetAddress()); 
         System.out.println(changer.toString()); 
         handleNameRequests(message); 
        } 
        else 
        { 
         tellEveryone(message, ip); // TEST CHANGE- DELETED IF TEST 
        } 
       } 
       // TEST TEST TEST 
       synchronized(clientOutputStreams) 
       { 
        int index = 
          clientOutputStreams.indexOf(
            socket.getOutputStream()); 
        clientOutputStreams.remove(index); 
        System.out.println("Removed the client in sync"); 
       } 
      } 
      // TEST TEST TEST 
      socket.close(); // TEST CLOSING SOCKET WHEN DONE. 
      System.out.println("Sock closed after while loop in ch run()"); 
     } 
     catch(IOException e) 
     { 
      System.out.println("IOException caught when " 
        + "reading message."); 
     } 
     catch (ClassNotFoundException e) 
     { 
      System.out.println("Some poor sap is going to have to debug" 
        + "this!"); 
     } 
     finally 
     { 
      // THIS WHOLE BLOCK: TEST TEST TEST 
      try 
      { 
       oInStream.close(); 
       System.out.println("just closed oinStream"); 
      } 
      catch(IOException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
+0

Crap, добавлена ​​старая версия источника, исправлена! – Airhead

+0

Исправлено! Я думаю, что это правильный код. Я много шутил с ним, пытаясь исправить это. – Airhead

ответ

0

Я НАСТОЯЩИМ НАЙДЕНО!

Для любых людей, сталкивающихся с подобной проблемой, проблема заключалась в том, что я назначал переменную ip в неположенном месте! Это по сути привело к тому, что список ip был одинаковым! Еще одна ошибка смутила эту проблему, когда я отключил возможность отправки сообщений, когда на моем shitlist (не являются программистами darndest?), Я отключил ВСЕ типы сообщений, в том числе от сервера, ect! К сожалению!

Урок? Ошибки прячутся в самых суровых местах. Пройдите через все и сомневайтесь, что вы знаете, чтобы быть правдой. Не предполагайте ничего, проверьте все. При отладке никогда не бывает утверждений о печати!

Смежные вопросы