根據馬士兵老師聊天室程序進行優化,同時增加聊天者之間的交互。
同時增加服務端會為每一個客戶端增加一個交互窗口,讓服務器可以和每一個客戶端交互!
服務端代碼
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.}