最近的项目有一个在线网页交流的需求,由于很久以前做过的demo已经忘记的差不多了,因此便重新学习一下。

 

我计划的大致实现步骤分这样几大步:

1、使用awt组件和socket实现简单的单客户端向服务端持续发送消息;

2、结合线程,实现多客户端连接服务端发送消息;

3、实现服务端转发客户端消息至所有客户端,同时在客户端显示;

4、把awt组件生成的窗口界面改成前端jsp或者html展示的界面,java socket实现的客户端改为前端技术实现。

 

这里首先实现第一步的简单功能,难点在于:

1、没有用过awt组件,没有用过java相关的监听事件;

2、长时间没有使用socket进行客户端和服务端的交互,并且没有真正进行过cs结构的开发。

 

实现功能的代码如下:

客户端:

1. package chat.chat;  
2.   
3. import java.awt.BorderLayout;  
4. import java.awt.Frame;  
5. import java.awt.TextArea;  
6. import java.awt.TextField;  
7. import java.awt.event.ActionEvent;  
8. import java.awt.event.ActionListener;  
9. import java.awt.event.WindowAdapter;  
10. import java.awt.event.WindowEvent;  
11. import java.io.DataOutputStream;  
12. import java.io.IOException;  
13. import java.net.Socket;  
14. import java.net.UnknownHostException;  
15.   
16. /** 
17.  * 在线聊天客户端 1、生成图形窗口界面轮廓 2、为轮廓添加关闭事件 3、在轮廓中加入输入区域和内容展示区域 4、为输入区域添加回车事件 
18.  * 5、建立服务端连接并发送数据 
19.  *  
20.  * @author tuzongxun123 
21.  * 
22.  */  
23. public class ChatClient extends Frame {  
24. // 用户输入区域  
25. private TextField tfTxt = new TextField();  
26. // 内容展示区域  
27. private TextArea tarea = new TextArea();  
28. private Socket socket = null;  
29. // 数据输出流  
30. private DataOutputStream dataOutputStream = null;  
31.   
32. public static void main(String[] args) {  
33. new ChatClient().launcFrame();  
34.     }  
35.   
36. /** 
37.      * 建立一个简单的图形化窗口 
38.      *  
39.      * @author:tuzongxun 
40.      * @Title: launcFrame 
41.      * @param 
42.      * @return void 
43.      * @date May 18, 2016 9:57:00 AM 
44.      * @throws 
45.      */  
46. public void launcFrame() {  
47. 300, 200);  
48. this.setSize(200, 400);  
49.         add(tfTxt, BorderLayout.SOUTH);  
50.         add(tarea, BorderLayout.NORTH);  
51.         pack();  
52. // 监听图形界面窗口的关闭事件  
53. this.addWindowListener(new WindowAdapter() {  
54.   
55. @Override  
56. public void windowClosing(WindowEvent e) {  
57. 0);  
58.                 disConnect();  
59.             }  
60.         });  
61. new TFLister());  
62. true);  
63.         connect();  
64.     }  
65.   
66. /** 
67.      * 连接服务器 
68.      *  
69.      * @author:tuzongxun 
70.      * @Title: connect 
71.      * @param 
72.      * @return void 
73.      * @date May 18, 2016 9:56:49 AM 
74.      * @throws 
75.      */  
76. public void connect() {  
77. try {  
78. // 新建服务端连接  
79. new Socket("127.0.0.1", 8888);  
80. // 获取客户端输出流  
81. new DataOutputStream(socket.getOutputStream());  
82. "连上服务端");  
83. catch (UnknownHostException e) {  
84.             e.printStackTrace();  
85. catch (IOException e) {  
86.             e.printStackTrace();  
87.         }  
88.     }  
89.   
90. /** 
91.      * 关闭客户端资源 
92.      *  
93.      * @author:tuzongxun 
94.      * @Title: disConnect 
95.      * @param 
96.      * @return void 
97.      * @date May 18, 2016 9:57:46 AM 
98.      * @throws 
99.      */  
100. public void disConnect() {  
101. try {  
102.             dataOutputStream.close();  
103.             socket.close();  
104. catch (IOException e) {  
105.             e.printStackTrace();  
106.         }  
107.     }  
108.   
109. /** 
110.      * 向服务端发送消息 
111.      *  
112.      * @author:tuzongxun 
113.      * @Title: sendMessage 
114.      * @param @param text 
115.      * @return void 
116.      * @date May 18, 2016 9:57:56 AM 
117.      * @throws 
118.      */  
119. private void sendMessage(String text) {  
120. try {  
121.             dataOutputStream.writeUTF(text);  
122.             dataOutputStream.flush();  
123. catch (IOException e1) {  
124.             e1.printStackTrace();  
125.         }  
126.     }  
127.   
128. /** 
129.      * 图形窗口输入区域监听回车事件 
130.      *  
131.      * @author tuzongxun123 
132.      * 
133.      */  
134. private class TFLister implements ActionListener {  
135.   
136. @Override  
137. public void actionPerformed(ActionEvent e) {  
138.             String text = tfTxt.getText().trim();  
139.             tarea.setText(text);  
140. "");  
141. // 回车后发送数据到服务器  
142.             sendMessage(text);  
143.         }  
144.     }  
145. }

 

服务端:

1. package chat.chat;  
2.   
3. import java.io.DataInputStream;  
4. import java.io.EOFException;  
5. import java.io.IOException;  
6. import java.net.BindException;  
7. import java.net.ServerSocket;  
8. import java.net.Socket;  
9.   
10. /** 
11.  * java使用socket和awt组件简单实现在线聊天功能服务端 可以实现一个客户端连接后不断向服务端发送消息 
12.  * 但不支持多个客户端同时连接,原因在于代码中获得客户端连接后会一直循环监听客户端输入,造成阻塞 
13.  * 以至于服务端无法二次监听另外的客户端,如要实现,需要使用异步或者多线程 
14.  *  
15.  * @author tuzongxun123 
16.  * 
17.  */  
18. public class ChatServer {  
19.   
20. public static void main(String[] args) {  
21. // 是否成功启动服务端  
22. boolean isStart = false;  
23. // 服务端socket  
24. null;  
25. // 客户端socket  
26. null;  
27. // 服务端读取客户端数据输入流  
28. null;  
29. try {  
30. // 启动服务器  
31. new ServerSocket(8888);  
32. catch (BindException e) {  
33. "端口已在使用中");  
34. // 关闭程序  
35. 0);  
36. catch (Exception e) {  
37.             e.printStackTrace();  
38.         }  
39.   
40. try {  
41. true;  
42. while (isStart) {  
43. boolean isConnect = false;  
44. // 启动监听  
45.                 socket = ss.accept();  
46. "one client connect");  
47. true;  
48. while (isConnect) {  
49. // 获取客户端输入流  
50. new DataInputStream(  
51.                             socket.getInputStream());  
52. // 读取客户端传递的数据  
53.                     String message = dataInputStream.readUTF();  
54. "客户端说:" + message);  
55.                 }  
56.   
57.             }  
58. catch (EOFException e) {  
59. "client closed!");  
60. catch (Exception e) {  
61.             e.printStackTrace();  
62. finally {  
63. // 关闭相关资源  
64. try {  
65.                 dataInputStream.close();  
66.                 socket.close();  
67. catch (IOException e) {  
68.                 e.printStackTrace();  
69.             }  
70.         }  
71.     }  
72. }