根據馬士兵老師聊天室程序進行優化,同時增加聊天者之間的交互。
同時增加服務端會為每一個客戶端增加一個交互窗口,讓服務器可以和每一個客戶端交互!
服務端代碼
1.import java.net.*;
2.import java.util.*;
3.import java.io.*;
4.import java.awt.*;
5.import java.awt.event.*;
6.import javax.swing.*;
7.
8.import javax.swing.JFrame;
9.
10.public class ChatServer extends JFrame {
11. JTextArea ta = new JTextArea();
12. ServerSocket server = null;
13. Collection cClient = new ArrayList();
14.
15. public ChatServer(int port) throws Exception {
16. server = new ServerSocket(port);
17. add(ta, BorderLayout.CENTER);
18. setBounds(200, 200, 300, 450);
19. this.addWindowListener(new WindowAdapter() {
20. public void windowClosing(WindowEvent e) {
21. System.exit(0);
22. }
23. });
24. setVisible(true);
25. }
26.
27. public void startServer() throws Exception {
28. while (true) {
29. Socket s = server.accept();
30. cClient.add(new ClientConn(s));
31. ta.append(s.getInetAddress().getHostName() + "進入" + " " + "端口號"
32. + s.getPort());
33. ta.append("\n" + "當前在前總人數: " + cClient.size() + "\n\n");
34. }
35. }
36.
37. class ClientConn extends Frame implements Runnable, ActionListener {
38. TextArea ta1 = null;
39. TextArea ta2 = null;
40. Button btn = null;
41. Socket s = null;
42.
43. public ClientConn(Socket s) {
44. ta1 = new TextArea(3, 30);
45. ta2 = new TextArea(2, 15);
46. btn = new Button("發送");
47. this.setLayout(new BorderLayout());
48. this.add(ta1, BorderLayout.CENTER);
49. this.add(ta2, BorderLayout.SOUTH);
50. this.add(btn, BorderLayout.EAST);
51. this.setSize(300, 200);
52. this.setVisible(true);
53. this.setTitle("" + s.getInetAddress().getHostName() + "端口"
54. + s.getPort());
55. this.s = s;
56. (new Thread(this)).start();
57. btn.addActionListener(this);
58. }
59.
60. public void actionPerformed(ActionEvent e) {
61. try {
62. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
63. dos.writeUTF("服務器:\n" + ta2.getText() + "\n");
64. ta1.append("服務器:\n" + ta2.getText() + "\n");
65. ta2.setText("");
66. } catch (IOException E) {
67.
68. }
69. }
70.
71. public void send(String str, String st) throws IOException {
72. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
73. dos.writeUTF(st + "說:\n" + str);
74. }
75.
76. public void dispose() {
77. try {
78. // this.setVisible(false);
79. super.dispose();
80. ta.append(s.getInetAddress().getHostName() + "退出" + "\n");
81. if (s != null)
82. s.close();
83. cClient.remove(this);
84. ta.append("當前在線人數: " + cClient.size() + "\n\n");
85. } catch (Exception e) {
86. e.printStackTrace();
87. }
88. }
89.
90. public void run() {
91. try {
92.
93. DataInputStream dis = new DataInputStream(s.getInputStream());
94. String str = dis.readUTF();
95. String st = s.getInetAddress().getHostName();
96. while (str != null && str.length() != 0) {
97. for (Iterator it = cClient.iterator(); it.hasNext();) {
98. ClientConn cc = (ClientConn) it.next();
99. if (this != cc) {
100. cc.send(str, st);
101. }
102. }
103. ta1.append(st + "說:\n" + str + "\n");
104. str = dis.readUTF();
105. }
106. this.dispose();
107. } catch (Exception e) {
108. this.dispose();
109. }
110.
111. }
112. }
113.
114. public static void main(String[] args) throws Exception {
115. JFrame.setDefaultLookAndFeelDecorated(true);
116. ChatServer cs = new ChatServer(8888);
117. cs.startServer();
118. }
119.}
客戶端代碼
1.import java.io.*;
2.import java.net.*;
3.import java.awt.*;
4.import java.awt.event.*;
5.import javax.swing.*;
6.
7.import javax.swing.JButton;
8.
9.public class ChatClient extends JFrame {
10. JTextArea ta = new JTextArea("你可以通過此客戶端的群聊!" + "\n" + "發送快捷鍵 ALT+ENTER \n");
11. TextArea tf = new TextArea(3, 21);
12. JButton btn = new JButton("發送");
13. JPanel jp = new JPanel();
14. Socket s = null;
15.
16. public ChatClient() throws Exception {
17. this.setLayout(new BorderLayout(10, 10));
18. this.add(ta, BorderLayout.CENTER);
19. jp.add(btn, BorderLayout.SOUTH);
20. this.add(tf, BorderLayout.SOUTH);
21. this.add(jp, BorderLayout.EAST);
22.
23. btn.addActionListener(new ActionListener() {
24. public void actionPerformed(ActionEvent ae) {
25. try {
26. String sSend = tf.getText();
27. if (sSend.trim().length() == 0)
28. return;
29. ChatClient.this.send(sSend);
30. tf.setText("");
31. ta.append("你自己說:" + "\n");
32. ta.append(sSend + "\n");
33. } catch (Exception e) {
34. e.printStackTrace();
35. }
36. }
37. });
38. btn.setMnemonic(KeyEvent.VK_ENTER);
39. this.addWindowListener(new WindowAdapter() {
40. public void windowClosing(WindowEvent e) {
41. System.exit(0);
42. }
43. });
44. setBounds(300, 300, 400, 500);
45. setVisible(true);
46. tf.requestFocus();
47. try {
48. s = new Socket("10.20.10.201", 8888);
49. } catch (Exception e) {
50. ta.append("對不起!無法連接服務器" + "\n");
51. }
52. (new Thread(new ReceiveThread())).start();
53. }
54.
55. public void send(String str) throws Exception {
56. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
57. dos.writeUTF(str);
58. }
59.
60. public void disconnect() throws Exception {
61. s.close();
62. }
63.
64. public static void main(String[] args) throws Exception {
65. JFrame.setDefaultLookAndFeelDecorated(true);
66. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
67. ChatClient cc = new ChatClient();
68. String str = br.readLine();
69. while (str != null && str.length() != 0) {
70. cc.send(str);
71. str = br.readLine();
72. }
73. cc.disconnect();
74. }
75.
76. class ReceiveThread implements Runnable {
77.
78. public void run() {
79. if (s == null)
80. return;
81. try {
82. DataInputStream dis = new DataInputStream(s.getInputStream());
83. String str = dis.readUTF();
84. while (str != null && str.length() != 0) {
85.
86. ChatClient.this.ta.append(str + "\n");
87. str = dis.readUTF();
88. }
89. } catch (Exception e) {
90. e.printStackTrace();
91. }
92.
93. }
94. }
95.}