1. 程式人生 > >java Socket實現簡單在線聊天(一)

java Socket實現簡單在線聊天(一)

結合線程 java.awt exc iss order 新建 exception connect border

出處:http://blog.csdn.net/tuzongxun 最近的項目有一個在線網頁交流的需求,由於很久以前做過的demo已經忘記的差不多了,因此便重新學習一下。 我計劃的大致實現步驟分這樣幾大步: 1、使用awt組件和socket實現簡單的單客戶端向服務端持續發送消息; 2、結合線程,實現多客戶端連接服務端發送消息; 3、實現服務端轉發客戶端消息至所有客戶端,同時在客戶端顯示; 4、把awt組件生成的窗口界面改成前端jsp或者html展示的界面,java socket實現的客戶端改為前端技術實現。 這裏首先實現第一步的簡單功能,難點在於: 1、沒有用過awt組件,沒有用過java相關的監聽事件; 2、長時間沒有使用socket進行客戶端和服務端的交互,並且沒有真正進行過cs結構的開發。 實現功能的代碼如下:
客戶端: [java] view plain copy
  1. package chat.chat;
  2. import java.awt.BorderLayout;
  3. import java.awt.Frame;
  4. import java.awt.TextArea;
  5. import java.awt.TextField;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.WindowAdapter;
  9. import java.awt.event.WindowEvent;
  10. import java.io.DataOutputStream;
  11. import java.io.IOException;
  12. import java.net.Socket;
  13. import java.net.UnknownHostException;
  14. /**
  15. * 在線聊天客戶端 1、生成圖形窗口界面輪廓 2、為輪廓添加關閉事件 3、在輪廓中加入輸入區域和內容展示區域 4、為輸入區域添加回車事件
  16. * 5、建立服務端連接並發送數據
  17. *
  18. * @author tuzongxun123
  19. *
  20. */
  21. public class ChatClient extends Frame {
  22. // 用戶輸入區域
  23. private TextField tfTxt = new TextField();
  24. // 內容展示區域
  25. private TextArea tarea = new TextArea();
  26. private Socket socket = null;
  27. // 數據輸出流
  28. private DataOutputStream dataOutputStream = null;
  29. public static void main(String[] args) {
  30. new ChatClient().launcFrame();
  31. }
  32. /**
  33. * 建立一個簡單的圖形化窗口
  34. *
  35. * @author:tuzongxun
  36. * @Title: launcFrame
  37. * @param
  38. * @return void
  39. * @date May 18, 2016 9:57:00 AM
  40. * @throws
  41. */
  42. public void launcFrame() {
  43. setLocation(300, 200);
  44. this.setSize(200, 400);
  45. add(tfTxt, BorderLayout.SOUTH);
  46. add(tarea, BorderLayout.NORTH);
  47. pack();
  48. // 監聽圖形界面窗口的關閉事件
  49. this.addWindowListener(new WindowAdapter() {
  50. @Override
  51. public void windowClosing(WindowEvent e) {
  52. System.exit(0);
  53. disConnect();
  54. }
  55. });
  56. tfTxt.addActionListener(new TFLister());
  57. setVisible(true);
  58. connect();
  59. }
  60. /**
  61. * 連接服務器
  62. *
  63. * @author:tuzongxun
  64. * @Title: connect
  65. * @param
  66. * @return void
  67. * @date May 18, 2016 9:56:49 AM
  68. * @throws
  69. */
  70. public void connect() {
  71. try {
  72. // 新建服務端連接
  73. socket = new Socket("127.0.0.1", 8888);
  74. // 獲取客戶端輸出流
  75. dataOutputStream = new DataOutputStream(socket.getOutputStream());
  76. System.out.println("連上服務端");
  77. } catch (UnknownHostException e) {
  78. e.printStackTrace();
  79. } catch (IOException e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. /**
  84. * 關閉客戶端資源
  85. *
  86. * @author:tuzongxun
  87. * @Title: disConnect
  88. * @param
  89. * @return void
  90. * @date May 18, 2016 9:57:46 AM
  91. * @throws
  92. */
  93. public void disConnect() {
  94. try {
  95. dataOutputStream.close();
  96. socket.close();
  97. } catch (IOException e) {
  98. e.printStackTrace();
  99. }
  100. }
  101. /**
  102. * 向服務端發送消息
  103. *
  104. * @author:tuzongxun
  105. * @Title: sendMessage
  106. * @param @param text
  107. * @return void
  108. * @date May 18, 2016 9:57:56 AM
  109. * @throws
  110. */
  111. private void sendMessage(String text) {
  112. try {
  113. dataOutputStream.writeUTF(text);
  114. dataOutputStream.flush();
  115. } catch (IOException e1) {
  116. e1.printStackTrace();
  117. }
  118. }
  119. /**
  120. * 圖形窗口輸入區域監聽回車事件
  121. *
  122. * @author tuzongxun123
  123. *
  124. */
  125. private class TFLister implements ActionListener {
  126. @Override
  127. public void actionPerformed(ActionEvent e) {
  128. String text = tfTxt.getText().trim();
  129. tarea.setText(text);
  130. tfTxt.setText("");
  131. // 回車後發送數據到服務器
  132. sendMessage(text);
  133. }
  134. }
  135. }


服務端: [java] view plain copy
  1. package chat.chat;
  2. import java.io.DataInputStream;
  3. import java.io.EOFException;
  4. import java.io.IOException;
  5. import java.net.BindException;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. /**
  9. * java使用socket和awt組件簡單實現在線聊天功能服務端 可以實現一個客戶端連接後不斷向服務端發送消息
  10. * 但不支持多個客戶端同時連接,原因在於代碼中獲得客戶端連接後會一直循環監聽客戶端輸入,造成阻塞
  11. * 以至於服務端無法二次監聽另外的客戶端,如要實現,需要使用異步或者多線程
  12. *
  13. * @author tuzongxun123
  14. *
  15. */
  16. public class ChatServer {
  17. public static void main(String[] args) {
  18. // 是否成功啟動服務端
  19. boolean isStart = false;
  20. // 服務端socket
  21. ServerSocket ss = null;
  22. // 客戶端socket
  23. Socket socket = null;
  24. // 服務端讀取客戶端數據輸入流
  25. DataInputStream dataInputStream = null;
  26. try {
  27. // 啟動服務器
  28. ss = new ServerSocket(8888);
  29. } catch (BindException e) {
  30. System.out.println("端口已在使用中");
  31. // 關閉程序
  32. System.exit(0);
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. try {
  37. isStart = true;
  38. while (isStart) {
  39. boolean isConnect = false;
  40. // 啟動監聽
  41. socket = ss.accept();
  42. System.out.println("one client connect");
  43. isConnect = true;
  44. while (isConnect) {
  45. // 獲取客戶端輸入流
  46. dataInputStream = new DataInputStream(
  47. socket.getInputStream());
  48. // 讀取客戶端傳遞的數據
  49. String message = dataInputStream.readUTF();
  50. System.out.println("客戶端說:" + message);
  51. }
  52. }
  53. } catch (EOFException e) {
  54. System.out.println("client closed!");
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. } finally {
  58. // 關閉相關資源
  59. try {
  60. dataInputStream.close();
  61. socket.close();
  62. } catch (IOException e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. }
  67. }

java Socket實現簡單在線聊天(一)