网络编程+多线程实现简单的聊天室功能

一:需求分析

1:聊天室:一个服务器,多个客户端,当一个客户端发送信息给服务器时,服务器会把

消息广播给其他的客户端用户。

2:服务器端,主线程一直处于阻塞状态,接受客户端请求,每当一个客户端发送请求过来

时,都会启动一个线程处理请求。

3:客户端,主线程负责向服务器通过控制台写数据,另外启动一个线程负责读取服务器端发送

过来的信息。

二:服务器端

 1 /**
 2  * 
 3  */
 4 package com.hlcui.socket;
 5 
 6 import java.io.BufferedReader;
 7 import java.io.IOException;
 8 import java.io.InputStreamReader;
 9 import java.io.PrintWriter;
10 import java.net.InetAddress;
11 import java.net.ServerSocket;
12 import java.net.Socket;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 
17 /**
18  * @author Administrator
19  * 
20  */
21 public class MyServer {
22     public static final int PORT = 8080;
23     public static List<Socket> socketList = Collections
24             .synchronizedList(new ArrayList<Socket>()); // 定义一个线程安全的list
25 
26     // 初始化
27     public void init() {
28 
29         try {
30             ServerSocket ss = new ServerSocket(PORT);
31             System.out.println("服务已经启动,等待客户端连接...");
32             // 主线程一直在监听端口
33             while (true) {
34                 Socket s = ss.accept();
35                 InetAddress inet = s.getInetAddress();
36                 System.out.println(inet.getHostAddress()+"上线了");
37                 socketList.add(s);
38                 new Thread(new ServerThread(s)).start(); // 启动线程处理客户端请求
39             }
40         } catch (IOException e) {
41             e.printStackTrace();
42         }
43     }
44 
45     public static void main(String[] args) {
46         MyServer server = new MyServer();
47         server.init();
48     }
49 }
50 
51 class ServerThread implements Runnable {
52     private BufferedReader br;
53     private Socket s;
54 
55     ServerThread(Socket s) throws IOException {
56         this.s = s;
57         br = new BufferedReader(new InputStreamReader(s.getInputStream()));
58     }
59 
60     @Override
61     public void run() {
62         String line = null;
63         while ((line = readClientContext()) != null) {
64             System.out.println(line);
65             // 将客户端数据广播出去(传递给每个客户端数据)
66             for (Socket s : MyServer.socketList) {
67                 try {
68                     PrintWriter pw = new PrintWriter(s.getOutputStream());
69                     pw.println(line);
70                     pw.flush();
71                     //pw.close();  //这里的pw一定不能关闭
72                 } catch (IOException e) {
73                     e.printStackTrace();
74                 }
75             }
76         }
77     }
78 
79     // 读取客户端数据
80     private String readClientContext() {
81         try {
82             return br.readLine();
83         } catch (IOException e) {
84             MyServer.socketList.remove(s);
85             System.out.println("读取客户端数据失败!");
86         }
87         return null;
88 
89     }
90 
91 }

三:客户端

 1 /**
 2  * 
 3  */
 4 package com.hlcui.socket;
 5 
 6 import java.io.BufferedReader;
 7 import java.io.IOException;
 8 import java.io.InputStreamReader;
 9 import java.io.PrintStream;
10 import java.net.Socket;
11 
12 /**
13  * @author Administrator
14  * 
15  */
16 public class MyClient {
17     public static final String IP = "127.0.0.1";
18     public static final int PORT = 8080;
19 
20     // 初始化
21     public void init() {
22         BufferedReader br = null;
23         PrintStream ps = null;
24         try {
25             Socket s = new Socket(IP, PORT);
26             // 启动线程读取服务器端发送的数据
27             new Thread(new ClientThread(s)).start();
28             // 控制台向服务器发送数据
29             br = new BufferedReader(new InputStreamReader(System.in));
30             ps = new PrintStream(s.getOutputStream());
31             String line = null;
32             while ((line = br.readLine()) != null) {
33                 ps.println(line);
34             }
35             ps.flush();
36         } catch (IOException e) {
37             e.printStackTrace();
38         } finally {
39             if (br != null) {
40                 try {
41                     br.close();
42                 } catch (IOException e) {
43                     e.printStackTrace();
44                 }
45             }
46             if (ps != null) {
47                 ps.close();
48             }
49         }
50     }
51 
52     public static void main(String[] args) {
53         MyClient client = new MyClient();
54         client.init();
55     }
56 
57 }
58 
59 class ClientThread implements Runnable {
60     private BufferedReader br;
61 
62     ClientThread(Socket s) {
63         try {
64             br = new BufferedReader(new InputStreamReader(s.getInputStream()));
65         } catch (IOException e) {
66             e.printStackTrace();
67         }
68     }
69 
70     @Override
71     public void run() {
72         String line = null;
73         try {
74             while ((line = br.readLine()) != null) {
75                 System.out.println(line);
76             }
77         } catch (IOException e) {
78             e.printStackTrace();
79         }
80     }
81 
82 }

 

原文地址:https://www.cnblogs.com/warrior4236/p/5683043.html