• 做这个项目前需要先做好分析:
  1. 聊天室分为两个模块,服务器和客户端。
  2. 服务器主要实现逻辑是:客户端第一次进入聊天室打印欢迎日志、接收客户端的消息打印在聊天室中、群发给其他用户、判断私聊的条件。
  3. 客户端主要实现逻辑是:初始化信息、发送消息给服务器、接收来自服务器的消息。
  • 项目从简单版本往上写,逐步增加功能:

     第一个版本:通过TCP搭建服务器和客户端,一个客户端上线服务器就打印一条上线提示。


     第二个版本:客户端发送一条消息,服务器接收一条,并反馈一条已接收的信息给客户端。


     第三个版本:通过多线程使客户端能不断给服务器发送消息,服务器也能不断回复客户端的信息。


     第四个版本:多个客户端开启时,自身发送的消息由服务器发给其他所有客户端,在聊天室中打印出以客户端姓名为前缀的每个人发出的消息。


     第五个版本:判断哪些是私聊的信息,私聊信息既不打印在聊天室中也只会发送给当前用户的私聊对象。完善代码。


  • 服务器代码:来一个客户端就开启一个服务器线程。具体逻辑放在线程中完成。
public 
 class 
 Server {
 
      
 public 
 static 
 void 
 main(String[] 
 args 
 ) 
 throws 
 IOException {
 
          List< ServerThread> 
 list 
 = 
 new 
 ArrayList<ServerThread>();
 
//判断私聊时需要知道发送给哪个客户端,所以把为每一个客户端服务的线程放入一个集合中。以此来遍历所以客户端。
 
          ServerSocket 
 serverSocket 
 = 
 new 
 ServerSocket(8080);
 
           
 while 
 ( 
 true 
 ){
 
              Socket 
 socket 
 = 
 serverSocket 
 .accept();
 
               ServerThread 
 serverThread 
 = 
 new 
 ServerThread( 
 socket 
 , 
 list 
 );
 
//开启线程时把当前客户端对应套接字和装有所有serverThread对象的集合传递给为当前客户端服务的线程。
 
               
 list 
 .add( 
 serverThread 
 );
 
//开启一个就往list中添加一个。
 
               
 serverThread 
 .start();
 
          }
 
     }
 
}
 
• 客户端代码:读入键盘输入数据,发送给服务器,并接收来自服务器的消息。读和写分别使用不同的线程。
public 
 class 
 Client {
 
      
 public 
 static 
 void 
 main(String[] 
 args 
 ) 
 throws 
 UnknownHostException, IOException {
 
          Socket 
 socket 
 = 
 new 
 Socket( 
 "10.2.155.91" 
 , 8080);
 
//通过服务器ip地址和服务器端口号建立与服务器的连接。
 
          WriterThread 
 writerThread 
 = 
 new 
 WriterThread( 
 socket 
 );
 
//开启一个写线程发送数据到服务器。
 
           
 writerThread 
 .start();
 
          ReaderThread 
 readerThread 
 = 
 new 
 ReaderThread( 
 socket 
 );
 
//开启一个读线程接收来自服务器的消息。
 
           
 readerThread 
 .start();
 
     }
 
}
 
• 服务器线程代码:
public 
 class 
 ServerThread 
 extends 
 Thread{
 
      
 private 
 Socket 
 socket 
 ;
 
      
 private 
 BufferedReader 
 bReader 
 ;
 
      
 private 
 BufferedWriter 
 bWriter 
 ;
 
      
 private 
 List<ServerThread> 
 list 
 ;
 
      
 private 
 String 
 name 
 ;
 
      
 public 
 ServerThread(Socket 
 socket 
 ,List<ServerThread> 
 list 
 ) {
 
           
 try 
 {
 
               
 this 
 . 
 socket 
 = 
 socket 
 ;
 
               
 this 
 . 
 list 
 = 
 list 
 ;
 
               
 bReader 
 = 
 new 
 BufferedReader( 
 new 
 InputStreamReader( 
 socket 
 .getInputStream()));
 
               
 bWriter 
 = 
 new 
 BufferedWriter( 
 new 
 OutputStreamWriter( 
 socket 
 .getOutputStream()));
 
          } 
 catch 
 (IOException 
 e 
 ) {
 
               
 e 
 .printStackTrace();
 
          }
 
     }
 
      
 public 
 void 
 run() {
 
          WelcomeChat();
 
           
 try 
 {
 
               
 while 
 ( 
 true 
 ){
 
                   String 
 info 
 = 
 bReader 
 .readLine();
 
                    
 if 
 ( 
 info 
 .startsWith( 
 "@" 
 )&& 
 info 
 .indexOf( 
 "#" 
 ) !=-1&&
 
                              
 info 
 .indexOf( 
 "#" 
 )- 
 info 
 .indexOf( 
 "@" 
 )>1) {
 
                        SendByName( 
 info 
 );
 
                   }
 
                    
 else 
 {
 
                        System. 
 out 
 .println( 
 name 
 + 
 "说:" 
 + 
 info 
 );
 
                        SendToOthers( 
 info 
 );
 
                   }
 
              }
 
          } 
 catch 
 (IOException 
 e 
 ) {
 
               
 e 
 .printStackTrace();
 
          }
 
     }
 
      
 private 
 void 
 WelcomeChat() {
 
           
 try 
 {
 
               
 name 
 = 
 bReader 
 .readLine();
 
              System. 
 out 
 .println( 
 "欢迎" 
 + 
 name 
 + 
 "进入聊天室" 
 );
 
          } 
 catch 
 (IOException 
 e1 
 ) {
 
               
 // 
 TODO 
 Auto-generated catch block
 
               
 e1 
 .printStackTrace();
 
          }
 
     }
 

 
      
 private 
 void 
 SendByName(String 
 info 
 ) 
 throws 
 IOException {
 
          String 
 name2 
 = 
 info 
 .substring( 
 info 
 .indexOf( 
 "@" 
 ) + 1, 
 info 
 .indexOf( 
 "#" 
 ));
 
           
 info 
 = 
 info 
 .substring( 
 info 
 .indexOf( 
 "#" 
 )+1);
 
           
 for 
 (ServerThread 
 serverThread 
 : 
 list 
 ) {
 
               
 if 
 ( 
 name2 
 .equals( 
 serverThread 
 . 
 name 
 )) {
 
                    
 bWriter 
 = 
 new 
 BufferedWriter( 
 new 
 OutputStreamWriter( 
 serverThread 
 . 
 socket 
 .getOutputStream()));
 
                    
 bWriter 
 .write( 
 name 
 + 
 "悄悄对你说:" 
 + 
 info 
 );
 
                    
 bWriter 
 .newLine();
 
                    
 bWriter 
 .flush();
 
                    
 break 
 ;
 
              }
 
          }
 
     }
 
      
 private 
 void 
 SendToOthers(String 
 info 
 ) 
 throws 
 IOException {
 
           
 for 
 (ServerThread 
 serverThread 
 : 
 list 
 ) {
 
               
 if 
 (Thread. currentThread()!= 
 serverThread 
 ) {
 
                    
 bWriter 
 = 
 new 
 BufferedWriter( 
 new 
 OutputStreamWriter( 
 serverThread 
 . 
 socket 
 .getOutputStream()));
 
                    
 bWriter 
 .write( 
 name 
 + 
 "说:" 
 + 
 info 
 );
 
                    
 bWriter 
 .newLine();
 
                    
 bWriter 
 .flush();
 
                   }
 
              }
 
          }
 
}