代码之家  ›  专栏  ›  技术社区  ›  Josh Curren

Java聊天服务器

  •  1
  • Josh Curren  · 技术社区  · 16 年前

    仅供参考,这是家庭作业。我必须建立一个Java聊天服务器。我已经能够构建一个与1个客户机通信的服务器。但是我需要这个来与多个用户通信。

    用户应该输入他们希望交谈的人的名字,然后输入破折号(-),然后输入要发送的消息。我可以让用户登录,但我无法获取要打印的用户列表或要发送给其他用户的消息。这是服务器代码:

    /** 
        Threaded Server
    */
    
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Scanner;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Set;
    
    public class ThreadedServer
    {
        public static void main( String[] args) throws Exception
        {
            HashMap<String, Socket> users = new HashMap<String, Socket>( );
            ServerSocket server = new ServerSocket(5679);
            System.out.println( "THE CHAT SERVER HAS STARTED! =)" );
            while(true)
            {
                Socket client = server.accept();
                ThreadedServer ser = new ThreadedServer();
                ClientFromThread cft =ser.new ClientFromThread(client);
                String name = cft.getUserName();
                users.put( name, client );
                cft.giveUsersMap( users );
                //cft.giveOnlineUsers( ); //DOES NOT WORK YET!!!!
                System.out.println("Threaded server connected to " 
                            + client.getInetAddress() + "  USER: " + name );            
            } 
    
        }
    
        //***************************************************************************************************
    
        class ClientFromThread extends Thread
        {
            private Socket client;
            private Scanner fromClient;
            private PrintWriter toClient;
            private String userName;
            HashMap<String, Socket> users;
    
            public ClientFromThread( Socket c ) throws Exception
            {
                client = c;
                fromClient = new Scanner( client.getInputStream() );
                toClient = new PrintWriter( client.getOutputStream(), true );
                userName = getUser();
                start();
            }
            public void giveUsersMap( HashMap<String, Socket> users )
            {
                this.users = users;
            }
    
            //THIS DOESNT WORK YET... IT PRINTS THE FIRST LINE BUT NOT THE LIST
            public void giveOnlineUsers()
            {
                toClient.println("These users are currently online:");
                Set<String> userList = users.keySet();
                String[] userNames = null;
                userList.toArray( userNames );
    
                for( int i = 0; i< userNames.length; i++ )
                {
                    toClient.println(userNames[i]);
                }
            }
    
            public String getUserName()
            {
                return userName;
            }
    
            private String getUser()
            {
                String s = "";
                while( (s.length() < 1) || (s == null) )
                {
                    toClient.println("What is your first name? ");
                    s=fromClient.nextLine().trim();
                }
                toClient.println("Thank You! Welcome to the chat room " + s + ".");
                return s.toUpperCase();
            }
    
            public void run() 
            {
                String s = null;
                String toUser;
                String mesg;
    
                while( (s=fromClient.nextLine().trim()) != null )
                {
                    if( s.equalsIgnoreCase( "END" )) break;
    
                    for( int i=0; i<s.length(); i++)
                    {
                        if( s.charAt(i) == '-' )
                        {
                            toUser = s.substring( 0, i ).trim().toUpperCase();
                            mesg = s.substring( i+1 ).trim();
                            Socket client = users.get( toUser );
                            try
                            {
                                ClientToThread ctt = new ClientToThread(client);
                                ctt.sendMesg( mesg, toUser );
                                ctt.start();
                            }
                            catch(Exception e){e.printStackTrace();}
                            break;
                        }
                        if( (i+1) == s.length() )
                        {
                            toClient.println("Sorry the text was invalid. Please enter a user name " +
                                                         "followed by a dash (-) then your message.");
                        }
                    }
                }
                try
                {
                    fromClient.close();
                    toClient.close();
                    client.close();
                }
                catch(Exception e){e.printStackTrace();}
            }
    
        } //end class ClientFromThread
    
        //***************************************************************************************************
    
        class ClientToThread extends Thread
        {
            private Socket client;
            private PrintWriter toClient;
            private String mesg;
    
            public ClientToThread( Socket c ) throws Exception
            {
                client = c;
                toClient = new PrintWriter( client.getOutputStream(), true );
            }
    
            public void sendMesg( String mesg, String userName )
            {
                this.mesg = userName + ": " + mesg;
            }
            public void run() 
            {
                toClient.println(mesg);
    
                try
                {
                    toClient.close();
                    client.close();
                }
                catch(Exception e){e.printStackTrace();}
            }
    
        } //end class ClientToThread
    
        //***************************************************************************************************
    
    } //end class ThreadedServer
    

    这是客户代码”

    import java.net.Socket;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    
    
    public class ReverseClient 
    {
    public static void main( String[] args ) throws Exception
    {
        String line = null;
        Socket server= new Socket( "10.0.2.103", 5679);
        System.out.println( "Connected to host: " + server.getInetAddress() );
        BufferedReader fromServer = new BufferedReader(
                    new InputStreamReader(server.getInputStream()) );
        PrintWriter toServer = new PrintWriter( server.getOutputStream(), true );
        BufferedReader input = new BufferedReader( 
                    new InputStreamReader(System.in) );
        while( (line=input.readLine()) !=null )
        {
            toServer.println(line);
            System.out.println( fromServer.readLine() );
        }
        fromServer.close();
        toServer.close();
        input.close();
        server.close();
    
    }   
    }
    

    下面是控制台输出(顶部是服务器,底部是客户端): alt text http://img269.imageshack.us/img269/4037/comandpromp.jpg

    我收到错误(如上图所示),消息没有发送。关于如何处理这些问题有什么建议吗?

    2 回复  |  直到 16 年前
        1
  •  1
  •   delux247    16 年前

    到目前为止,我发现这是个问题,但我不认为这是唯一的问题。

    这将有助于NosuchelementException 在第90行左右改变这个…

    while( (s=fromClient.nextLine().trim()) != null )
    {
    

    对此…

    while(fromClient.hasNext())
    {
       s = fromClient.nextLine().trim();
    

    OK刚刚在clientToThread.run()中发现另一个问题。发送第一条消息后,您将关闭客户端连接。我把他们都说出来了,似乎工作得更好。

    public void run()
      {
         toClient.println(mesg);
         try {
            //toClient.close();
            //client.close();
         }
         catch (Exception e)  {
            e.printStackTrace();
         }
      }
    
        2
  •  0
  •   James Black    16 年前

    第一个问题是解析来自用户的消息。

    循环遍历字符串,它有两个选项之一,要么是破折号,要么是无效的。

    因此,理想情况下,在破折号之前,您应该会收到一条关于用户名中字符数的无效消息。

    您应该使用string.indexof来确定破折号的位置,然后将消息分成两部分,如果indexof的结果是-1,则它是无效消息。

    推荐文章