最近的项目有一个在线网页交流的需求,由于很久以前做过的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. }