Java聊天奇怪的bug

时间:2013-12-02 22:52:41

标签: java

我正在尝试创建一个java聊天,我遇到了这个错误:当我使用name = scanner.nextLine()时,我的程序工作得很好(但如果我使用System.out,它不会读取任何名称) .println(name)我得到了换行符),当我不使用它时,我的pg会自动连接到没有名字的服务器。任何人都可以告诉我为什么会发生这种情况吗?

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

class Cient 
{  
    static String name;

      public static void main(String[] args) throws Exception
      {
          Scanner scanner = new Scanner(System.in); 
          System.out.print("Adresa serverului si portul : ");//server adress and port
          Socket cs = new Socket( scanner.next(), scanner.nextInt() ); 
          DataOutputStream os = new DataOutputStream( cs.getOutputStream()); 
          final DataInputStream is = new DataInputStream( cs.getInputStream());
          String st = "";

            System.out.println("Va rugam sa va introduceti numele");//get name
            name = scanner.nextLine();
          Thread T= new Thread(new Runnable()
          {  
                 public void run() {
                  while (true)
                  {
                      String s = ""; 
                      try
                      {
                          s = is.readUTF();
                          System.out.println(s); 
                          if(s.equals("Intrerupem conexiunea .... Pa!"))//close connexion
                          {
                              return;
                          }
                      } catch (IOException ex)
                      {

                      }

                  }
              }
          });

          T.start();
          while (true) 
          { 
              st = scanner.nextLine();
              os.writeUTF(st);

              if(st.equals("QUIT") || st.equals("EXIT"))
              {
                  return;//stop reading
              }
          }
      }
}

这是服务器类,但我不相信这很重要:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.Vector;

public class MyServer 
{
    Scanner scanner;
    Vector<String> users = new Vector<String>();
    Vector<HandleClient> clients = new Vector<HandleClient>();
    String disconnectedUser = "InvalidUser";//String care imi spune daca un client s-a razgandit la conectare
    int PORT;  

  public Vector<String> getUserList()
  {
      return users;
  }

  public void process() throws Exception  
  {
      scanner = new Scanner(System.in);
      System.out.println("PORT: ");

      PORT = scanner.nextInt();
      ServerSocket server = new ServerSocket(PORT);
      System.out.println("Server Online...");
      while(true) 
      {
         Socket client = server.accept();
         HandleClient c = new HandleClient(client);
         if(!(c.userName().equals(disconnectedUser)))
         {
             clients.add(c);
             users.add(c.userName());
         }
     }
  }

  public static void main(String ... args) throws Exception 
  {
      new MyServer().process();
  } 

  public void  broadcast(String user, String message)throws Exception  
  {
        for (HandleClient c : clients)
           if (!(c.userName().equals(user)))
           {
              c.sendMessage(user,message);
           }
  }

  public void twoUsersBroadcast(String fromUser,String toUser, String msg)throws Exception
  {
      for(HandleClient c : clients)
      {
        String a = (String) c.userName();
        if(a.equals(toUser))
        {
          c.sendMessage(fromUser,msg);
          return ;
        }
      }
  }

  public void changeUserName(String actualName,String newName)
  {
    int i = 0;
    for(HandleClient c: clients)
    {
      if(c.userName().equals(actualName))
      {
        c.setUserName(newName);
        users.set(i,newName);
      }
      i++;
    }
  }


  boolean validUserName(String name)
  {
    for(String c : users)
    {
      if(c.equals(name))
      {
        return false;
      }
    }
    return true;
  }

  class HandleClient extends Thread 
  {
    String name = "";
    DataInputStream input;
    DataOutputStream output;

    public String userName() 
    {
        return name;
    }

    public void setUserName(String name)
    {
        this.name = name;
    }

    public void writeError(String message)
    {
        try 
        {
            output.writeUTF("EROARE: " + message);
        }
        catch (IOException e) 
        {
            System.out.print(e.getMessage());
        }
    }

    public HandleClient(Socket client)throws Exception
    {
        input = new DataInputStream(client.getInputStream());
        output= new DataOutputStream(client.getOutputStream());

        boolean ok = true;

        while(ok == true)
        {
            name = input.readUTF();
            if(name.equals("EXIT"))
            {
                ok = false;
                output.writeUTF("Intrerupem conexiunea .... Pa!");
                name = "InvalidUser";//User-ul a renuntat la conexiune
            }
            else
            {
                if(validUserName(name) == true)
                {
                    ok = false;
                }
                else
                {
                    output.writeUTF("Numele este deja folosit. Va rugam sa introducet un alt nume sau EXIT in care doriti sa nu va mai conectati");
                }
            }
        }
        if("InvalidUser".equals(name))
        {

            return;
        }
          start(); 
    }

    public void sendMessage(String username,String  msg)throws Exception  
    {
        output.writeUTF( username + ": " + msg);
    }

    public void run()  
    {
         String line;
         try    
         { 
            boolean ok = true;
            output.writeUTF("Introduceti:");
            output.writeUTF("LIST pentru a vedea lista de utilizatori");
            output.writeUTF("MSG pentru a transmite un mesaj unui anumit utilizator");
            output.writeUTF("BCAST pentru a transmite un mesaj tuturor utilizatorilor");
            output.writeUTF("NICK pentru a va schimba numele");
            output.writeUTF("QUIT pentru a va deconecta de la server");

            while(ok == true)   
            {
                line = input.readUTF();
                switch(line)
                {
                    case "LIST":
                    {

                        Vector<String> users = getUserList();
                        output.writeUTF("Lista user-ilor este:");
                        for(String c : users)
                        {
                            output.writeUTF(c);
                        }
                        break;
                    }

                    case "MSG":
                    {
                        output.writeUTF("Introduceti numele persoanei careia doriti sa-i trimiteti mesajul");
                        line = input.readUTF();
                        if(validUserName(line) == true)
                        {
                            writeError("Numele persoanei nu exista");
                            break;
                        }
                        else
                        {
                            if(name.equals(line))
                            {
                                writeError("Selectati alt user");
                                break;
                            }
                            else
                            {
                                output.writeUTF("Introduceti mesajul pe care il aveti de transmis");
                                String message = input.readUTF();
                                if((validUserName(line) == false) && !(line.equals(name)))
                                {
                                    twoUsersBroadcast(name,line,message);
                                }
                                break;
                            }
                        }
                    }

                    case "BCAST":
                    {
                        line = input.readUTF();
                        broadcast(name,line);
                        break;
                    }

                    case "NICK":
                    {
                        output.writeUTF("Va rugam sa va introduceti numele dorit");
                        line = input.readUTF();

                        if(validUserName(line))
                        {
                            changeUserName(name,line);
                        }
                        else
                        {
                            writeError("Invalid username");
                        }
                        break;
                    }

                    case "QUIT":
                    {
                        output.writeUTF("Intrerupem conexiunea .... Pa!");
                        clients.remove(this);
                        users.remove(name);
                        ok = true;
                        break;
                    }

                    default:
                    {
                        writeError("Comanda incorecta");
                    }
                }
            }
        } 
         catch(Exception e) 
         {
           System.err.println(e.getMessage());
           clients.remove(this);
           users.remove(name);
         }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

这一行之后:

Socket cs = new Socket( scanner.next(), scanner.nextInt() ); 

添加:

scanner.nextLine();

所以在一起,它看起来像:

Socket cs = new Socket( scanner.next(), scanner.nextInt() ); 
scanner.nextLine();

这样做是为了吞下未由next()nextInt()处理的悬空行尾(EOL)令牌,实际上只由nextLine()处理。