好了下面講一下基本的思路:java
首先,編寫服務器端的程序,簡單點說吧就是在服務上開啓一個線程循環等待客戶端的鏈接,爲每個鏈接到服務器的Socket 建立一個實例存放在集合中,而後使用InputSteam讀取從客戶端發過來的數據而後轉發給除本身以外的全部的客戶端json
而後是客戶端,首先開啓一個線程鏈接都服務器端,循環監聽服務器發送回來的數據服務器
這裏要說一下爲了明確是誰發出的消息我在這裏採用了JSON的數據格式進行消息的傳遞在客戶端對服務器端的數據進行JSON格式的解析顯示到文本區app
下面貼出客戶端的源碼(這裏沒有進行分包請你們諒解):socket
package com.chact; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JOptionPane; import org.json.JSONException; import org.json.JSONObject; @SuppressWarnings("serial") public class ChactClient extends Frame { /** * 定義全部要使用的成員變量。 * */ public String Other = null; public Button mButton = new Button("使用名稱"); public static TextField mTextField = new TextField(20); public static TextField usernameTextField = new TextField(20); public static TextArea mTextArea = new TextArea(30, 30); public static Boolean Flag; Socket socket = null; static StringBuffer stringBuffer = new StringBuffer(); public static Socket s = null; OutputStream outputStream = null; OutputStreamWriter writer = null; static String ChactContent = null; /** * * 定義的主方法 * * @param args * @throws UnknownHostException * @throws IOException */ public static void main(String[] args) throws UnknownHostException, IOException { new ChactClient().launchFrame(); /** * 開啓一個新的線程用來鏈接到服務器端 */ Thread mThread = new Thread() { @Override public void run() { try { s = new Socket("123.206.76.188", 12345); } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } /********************************************************************************/ /** * * 循環的從服務器讀取數據 * */ while (true) { try { InputStream iso = s.getInputStream(); InputStreamReader sior = new InputStreamReader(iso, "UTF-8"); BufferedReader bufferedReader = new BufferedReader(sior); String string; while ((string = bufferedReader.readLine()) != null) { System.out.println(string); // 這裏使用JSON數據格式進行數據的傳遞 JSONObject jsonObject = new JSONObject(string); // 若是數據是本身發送的就沒必要再進行讀取和顯示 if (!jsonObject.getString("username").equals(usernameTextField.getText().trim())) { mTextArea.append(jsonObject.getString("username") + ": " + jsonObject.getString("Content") + "\n"); mTextArea.setForeground(Color.CYAN); stringBuffer = null; } else { stringBuffer = null; } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; mThread.start(); } /****************************************************************************/ /** * * 定義可見的窗口 * * @throws UnknownHostException * @throws IOException */ public void launchFrame() throws UnknownHostException, IOException { Frame frame = new Frame(); frame.setTitle("開拓者即時聊天系統"); frame.setLocation(300, 300); // this.setBounds(300,300,300,300); frame.setSize(600, 800); frame.setResizable(false); frame.add(mButton, BorderLayout.LINE_START); frame.add(usernameTextField, BorderLayout.LINE_END); frame.add(mTextArea, BorderLayout.NORTH); frame.add(mTextField, BorderLayout.SOUTH); mTextArea.setFont(new Font("微軟雅黑", Font.PLAIN, 15)); frame.pack(); mTextField.addActionListener(new TFlistener()); mTextArea.setEditable(false); mTextField.setEditable(false); mButton.addActionListener(new ActionListener() { /** * 首先進行用戶名的讀取若是爲空則提示先輸入用戶名 * * */ @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // String Other; Other = usernameTextField.getText().trim(); Other = Other.replace('\n', ' '); // System.out.println(Other); if (!Other.equals("")) { usernameTextField.setEditable(false); mTextField.setEditable(true); } else { JOptionPane.showMessageDialog(null, "暱稱不能爲空!", "標題", JOptionPane.INFORMATION_MESSAGE); } } }); /** * * 定義關閉窗口的的事件監聽器 * */ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { // 提示對方下線的JSON數據 String JSON = "{" + "'username'" + ":" + Other + ',' + "'Content'" + ":" + "已下線!!!" + "}"; try { outputStream = socket.getOutputStream(); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } try { writer = new OutputStreamWriter(outputStream, "UTF-8"); } catch (UnsupportedEncodingException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } try { writer.write(JSON + "\n"); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } try { writer.flush(); } catch (IOException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } System.exit(0); try { socket.close(); destory(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }); frame.setVisible(true); // 獲取與服務器的鏈接 Contection(); } /** * * 定義與服務器鏈接的函數 * * @throws UnknownHostException * @throws IOException */ public void Contection() throws UnknownHostException, IOException { socket = new Socket("123.206.76.188", 12345); System.out.println("成功鏈接到客戶端"); } /** * * 監聽回車鍵進行數據的發送的監聽器 * * * @author Administrator-SYSTEM * */ private class TFlistener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { ChactContent = mTextField.getText().trim(); try { String JSON = "{" + "'username'" + ":" + Other + ',' + "'Content'" + ":" + ChactContent + "}"; outputStream = socket.getOutputStream(); writer = new OutputStreamWriter(outputStream, "UTF-8"); writer.write(JSON + "\n"); writer.flush(); mTextArea.setForeground(Color.BLACK); mTextArea.append("我說: " + ChactContent + "\n"); mTextField.setText(""); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } // 進行資源的釋放 public void destory() throws IOException { outputStream.close(); writer.close(); socket.close(); } }