激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 網(wǎng)頁(yè)版在線聊天java Socket實(shí)現(xiàn)

網(wǎng)頁(yè)版在線聊天java Socket實(shí)現(xiàn)

2020-05-03 13:56lijiao JAVA教程

這篇文章主要為大家詳細(xì)介紹了java Socket實(shí)現(xiàn)網(wǎng)頁(yè)版在線聊天具體代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文為大家分享了一個(gè)滿足在線網(wǎng)頁(yè)交流需求的實(shí)例,由于java Socket實(shí)現(xiàn)的網(wǎng)頁(yè)版在線聊天功能,供大家參考,具體內(nèi)容如下

實(shí)現(xiàn)步驟:
1、使用awt組件和socket實(shí)現(xiàn)簡(jiǎn)單的單客戶端向服務(wù)端持續(xù)發(fā)送消息;
2、結(jié)合線程,實(shí)現(xiàn)多客戶端連接服務(wù)端發(fā)送消息;
3、實(shí)現(xiàn)服務(wù)端轉(zhuǎn)發(fā)客戶端消息至所有客戶端,同時(shí)在客戶端顯示;
4、把a(bǔ)wt組件生成的窗口界面改成前端jsp或者h(yuǎn)tml展示的界面,java socket實(shí)現(xiàn)的客戶端改為前端技術(shù)實(shí)現(xiàn)。

這里首先實(shí)現(xiàn)第一步的簡(jiǎn)單功能,難點(diǎn)在于:
1、沒(méi)有用過(guò)awt組件,沒(méi)有用過(guò)java相關(guān)的監(jiān)聽(tīng)事件;
2、長(zhǎng)時(shí)間沒(méi)有使用socket進(jìn)行客戶端和服務(wù)端的交互,并且沒(méi)有真正進(jìn)行過(guò)cs結(jié)構(gòu)的開(kāi)發(fā)。

實(shí)現(xiàn)功能的代碼
在線聊天客戶端:
1、生成圖形窗口界面輪廓
2、為輪廓添加關(guān)閉事件
3、在輪廓中加入輸入?yún)^(qū)域和內(nèi)容展示區(qū)域
4、為輸入?yún)^(qū)域添加回車(chē)事件
5、建立服務(wù)端連接并發(fā)送數(shù)據(jù)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package chat.chat;
 
import java.awt.BorderLayout;
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.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
 
/**
 * 在線聊天客戶端 1、生成圖形窗口界面輪廓 2、為輪廓添加關(guān)閉事件 3、在輪廓中加入輸入?yún)^(qū)域和內(nèi)容展示區(qū)域 4、為輸入?yún)^(qū)域添加回車(chē)事件
 * 5、建立服務(wù)端連接并發(fā)送數(shù)據(jù)
 *
 * @author tuzongxun123
 *
 */
public class ChatClient extends Frame {
  // 用戶輸入?yún)^(qū)域
  private TextField tfTxt = new TextField();
  // 內(nèi)容展示區(qū)域
  private TextArea tarea = new TextArea();
  private Socket socket = null;
  // 數(shù)據(jù)輸出流
  private DataOutputStream dataOutputStream = null;
 
  public static void main(String[] args) {
    new ChatClient().launcFrame();
  }
 
  /**
   * 建立一個(gè)簡(jiǎn)單的圖形化窗口
   *
   * @author:tuzongxun
   * @Title: launcFrame
   * @param
   * @return void
   * @date May 18, 2016 9:57:00 AM
   * @throws
   */
  public void launcFrame() {
    setLocation(300, 200);
    this.setSize(200, 400);
    add(tfTxt, BorderLayout.SOUTH);
    add(tarea, BorderLayout.NORTH);
    pack();
    // 監(jiān)聽(tīng)圖形界面窗口的關(guān)閉事件
    this.addWindowListener(new WindowAdapter() {
 
      @Override
      public void windowClosing(WindowEvent e) {
        System.exit(0);
        disConnect();
      }
    });
    tfTxt.addActionListener(new TFLister());
    setVisible(true);
    connect();
  }
 
  /**
   * 連接服務(wù)器
   *
   * @author:tuzongxun
   * @Title: connect
   * @param
   * @return void
   * @date May 18, 2016 9:56:49 AM
   * @throws
   */
  public void connect() {
    try {
      // 新建服務(wù)端連接
      socket = new Socket("127.0.0.1", 8888);
      // 獲取客戶端輸出流
      dataOutputStream = new DataOutputStream(socket.getOutputStream());
      System.out.println("連上服務(wù)端");
    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
 
  /**
   * 關(guān)閉客戶端資源
   *
   * @author:tuzongxun
   * @Title: disConnect
   * @param
   * @return void
   * @date May 18, 2016 9:57:46 AM
   * @throws
   */
  public void disConnect() {
    try {
      dataOutputStream.close();
      socket.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
 
  /**
   * 向服務(wù)端發(fā)送消息
   *
   * @author:tuzongxun
   * @Title: sendMessage
   * @param @param text
   * @return void
   * @date May 18, 2016 9:57:56 AM
   * @throws
   */
  private void sendMessage(String text) {
    try {
      dataOutputStream.writeUTF(text);
      dataOutputStream.flush();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }
 
  /**
   * 圖形窗口輸入?yún)^(qū)域監(jiān)聽(tīng)回車(chē)事件
   *
   * @author tuzongxun123
   *
   */
  private class TFLister implements ActionListener {
 
    @Override
    public void actionPerformed(ActionEvent e) {
      String text = tfTxt.getText().trim();
      tarea.setText(text);
      tfTxt.setText("");
      // 回車(chē)后發(fā)送數(shù)據(jù)到服務(wù)器
      sendMessage(text);
    }
  }
}

服務(wù)端:

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

繼續(xù),在單客戶端連接的基礎(chǔ)上,這里第二步需要實(shí)現(xiàn)多客戶端的連接,也就需要使用到線程。每當(dāng)有一個(gè)新的客戶端連接上來(lái),服務(wù)端便需要新啟動(dòng)一個(gè)線程進(jìn)行處理,從而解決之前的循環(huán)讀取中造成阻塞的問(wèn)題。

寫(xiě)線程通常有兩種方法,集成Thread或者實(shí)現(xiàn)runnable接口,原則上是能實(shí)現(xiàn)runnable的情況下就不繼承,因?yàn)閷?shí)現(xiàn)接口的方式更加靈活。

客戶端代碼相較之前沒(méi)有變化,變得是服務(wù)端,因此這里便只貼出服務(wù)端代碼:

java使用socket和awt組件以及多線程簡(jiǎn)單實(shí)現(xiàn)在線聊天功能服務(wù)端 :

實(shí)現(xiàn)多個(gè)客戶端連接后不斷向服務(wù)端發(fā)送消息, 相對(duì)于第一個(gè)版本,重點(diǎn)在于使用了多線程。服務(wù)端還未實(shí)現(xiàn)轉(zhuǎn)發(fā)功能,客戶端圖形窗口中只能看到自己輸入的信息,不能看到其他客戶端發(fā)送的消息。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package chat.chat;
 
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
 
/**
 * *
 * @author tuzongxun123
 *
 */
public class ChatServer {
 
  public static void main(String[] args) {
    new ChatServer().start();
  }
 
  // 是否成功啟動(dòng)服務(wù)端
  private boolean isStart = false;
  // 服務(wù)端socket
  private ServerSocket ss = null;
  // 客戶端socket
  private Socket socket = null;
 
  public void start() {
    try {
      // 啟動(dòng)服務(wù)器
      ss = new ServerSocket(8888);
    } catch (BindException e) {
      System.out.println("端口已在使用中");
      // 關(guān)閉程序
      System.exit(0);
    } catch (Exception e) {
      e.printStackTrace();
    }
 
    try {
      isStart = true;
      while (isStart) {
        // 啟動(dòng)監(jiān)聽(tīng)
        socket = ss.accept();
        System.out.println("one client connect");
        // 啟動(dòng)客戶端線程
        Client client = new Client(socket);
        new Thread(client).start();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 關(guān)閉服務(wù)
      try {
        ss.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
 
  }
 
  /**
   * 客戶端線程
   *
   * @author tuzongxun123
   *
   */
  class Client implements Runnable {
    // 客戶端socket
    private Socket socket = null;
    // 客戶端輸入流
    private DataInputStream dataInputStream = null;
    private boolean isConnect = false;
 
    public Client(Socket socket) {
      this.socket = socket;
      try {
        isConnect = true;
        // 獲取客戶端輸入流
        dataInputStream = new DataInputStream(socket.getInputStream());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
 
    @Override
    public void run() {
      isConnect = true;
      try {
        while (isConnect) {
          // 讀取客戶端傳遞的數(shù)據(jù)
          String message = dataInputStream.readUTF();
          System.out.println("客戶端說(shuō):" + message);
        }
      } catch (EOFException e) {
        System.out.println("client closed!");
      } catch (SocketException e) {
        System.out.println("Client is Closed!!!!");
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        // 關(guān)閉相關(guān)資源
        try {
          dataInputStream.close();
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
 
  }
 
}

上面主要介紹了利用線程使服務(wù)端實(shí)現(xiàn)了能夠接收多客戶端請(qǐng)求的功能,這里便需要客戶端接收多客戶端消息的同時(shí)還能把消息轉(zhuǎn)發(fā)到每個(gè)連接的客戶端,并且客戶端要能在內(nèi)容顯示區(qū)域顯示出來(lái),從而實(shí)現(xiàn)簡(jiǎn)單的在線群聊。

在實(shí)現(xiàn)客戶端轉(zhuǎn)發(fā),無(wú)非就是增加輸出流;而之前客戶端都只發(fā)不收,這里也需要更改客戶端達(dá)到循環(huán)接收服務(wù)端消息的目的,因此也需要實(shí)現(xiàn)多線程。

在實(shí)現(xiàn)這個(gè)功能的時(shí)候,偶然想起隨機(jī)生成驗(yàn)證碼的功能,于是也靈機(jī)一動(dòng)隨機(jī)給每個(gè)客戶端生成一個(gè)名字,從而在輸出的時(shí)候看起來(lái)更加像是群聊,不僅有消息輸出,還能看到是誰(shuí)。

實(shí)現(xiàn)這些功能之后,基本上就可以幾個(gè)人同時(shí)在線群聊了,因?yàn)榇a中有main方法,因此可以把服務(wù)端和客戶端都打成可執(zhí)行jar包,可參考我的另一篇博文:使用eclipse創(chuàng)建java程序可執(zhí)行jar包

之后在桌面雙擊相應(yīng)的jar文件啟動(dòng)服務(wù)端和客戶端即可,不需要再依賴eclipse運(yùn)行。

修改后的客戶端代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
package chat.chat;
 
import java.awt.BorderLayout;
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.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
 
/**
 * 在線聊天客戶端 步驟:
 
 *1、生成圖形窗口界面輪廓
 
 *2、為輪廓添加關(guān)閉事件
 
 *3、在輪廓中加入輸入?yún)^(qū)域和內(nèi)容展示區(qū)域
 
 *4、為輸入?yún)^(qū)域添加回車(chē)事件
 * 5、建立服務(wù)端連接并發(fā)送數(shù)據(jù)
 *
 * @author tuzongxun123
 *
 */
public class ChatClient extends Frame {
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  // 用戶輸入?yún)^(qū)域
  private TextField tfTxt = new TextField();
  // 內(nèi)容展示區(qū)域
  private TextArea tarea = new TextArea();
  private Socket socket = null;
  // 數(shù)據(jù)輸出流
  private DataOutputStream dataOutputStream = null;
  // 數(shù)據(jù)輸入流
  private DataInputStream dataInputStream = null;
  private boolean isConnect = false;
  Thread tReceive = new Thread(new ReceiveThread());
  String name = "";
 
  public static void main(String[] args) {
    ChatClient chatClient = new ChatClient();
    chatClient.createName();
    chatClient.launcFrame();
 
  }
 
  /**
   * 建立一個(gè)簡(jiǎn)單的圖形化窗口
   *
   * @author:tuzongxun
   * @Title: launcFrame
   * @param
   * @return void
   * @date May 18, 2016 9:57:00 AM
   * @throws
   */
  public void launcFrame() {
    setLocation(300, 200);
    this.setSize(200, 400);
    add(tfTxt, BorderLayout.SOUTH);
    add(tarea, BorderLayout.NORTH);
    // 根據(jù)窗口里面的布局及組件的preferedSize來(lái)確定frame的最佳大小
    pack();
    // 監(jiān)聽(tīng)圖形界面窗口的關(guān)閉事件
    this.addWindowListener(new WindowAdapter() {
 
      @Override
      public void windowClosing(WindowEvent e) {
        System.exit(0);
        disConnect();
      }
    });
    tfTxt.addActionListener(new TFLister());
    // 設(shè)置窗口可見(jiàn)
    setVisible(true);
    connect();
    // 啟動(dòng)接受消息的線程
    tReceive.start();
  }
 
  /**
   * 連接服務(wù)器
   *
   * @author:tuzongxun
   * @Title: connect
   * @param
   * @return void
   * @date May 18, 2016 9:56:49 AM
   * @throws
   */
  public void connect() {
    try {
      // 新建服務(wù)端連接
      socket = new Socket("127.0.0.1", 8888);
      // 獲取客戶端輸出流
      dataOutputStream = new DataOutputStream(socket.getOutputStream());
      dataInputStream = new DataInputStream(socket.getInputStream());
      System.out.println("連上服務(wù)端");
      isConnect = true;
    } catch (UnknownHostException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
 
  // 生成隨機(jī)的客戶端名字
  public void createName() {
    String[] str1 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
        "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
        "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8",
        "9", "0", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
        "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
        "W", "X", "Y", "Z" };
    Random ran = new Random();
 
    for (int i = 0; i < 6; i++) {
      // long num = Math.round(Math.random() * (str1.length - 0) + 0);
      // int n = (int) num;
      int n = ran.nextInt(str1.length);
      if (n < str1.length) {
        String str = str1[n];
        name = name + str;
        System.out.println(name);
      } else {
        i--;
        continue;
      }
 
    }
    this.setTitle(name);
  }
 
  /**
   * 關(guān)閉客戶端資源
   *
   * @author:tuzongxun
   * @Title: disConnect
   * @param
   * @return void
   * @date May 18, 2016 9:57:46 AM
   * @throws
   */
  public void disConnect() {
    try {
      isConnect = false;
      // 停止線程
      tReceive.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      try {
        if (dataOutputStream != null) {
          dataOutputStream.close();
        }
        if (socket != null) {
          socket.close();
          socket = null;
        }
 
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
 
  /**
   * 向服務(wù)端發(fā)送消息
   *
   * @author:tuzongxun
   * @Title: sendMessage
   * @param @param text
   * @return void
   * @date May 18, 2016 9:57:56 AM
   * @throws
   */
  private void sendMessage(String text) {
    try {
      dataOutputStream.writeUTF(name + ":" + text);
      dataOutputStream.flush();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }
 
  /**
   * 圖形窗口輸入?yún)^(qū)域監(jiān)聽(tīng)回車(chē)事件
   *
   * @author tuzongxun123
   *
   */
  private class TFLister implements ActionListener {
 
    @Override
    public void actionPerformed(ActionEvent e) {
      String text = tfTxt.getText().trim();
      // 清空輸入?yún)^(qū)域信息
      tfTxt.setText("");
      // 回車(chē)后發(fā)送數(shù)據(jù)到服務(wù)器
      sendMessage(text);
    }
 
  }
 
  private class ReceiveThread implements Runnable {
 
    @Override
    public void run() {
      try {
        while (isConnect) {
          String message = dataInputStream.readUTF();
          System.out.println(message);
          String txt = tarea.getText();
          if (txt != null && !"".equals(txt.trim())) {
            message = tarea.getText() + "\n" + message;
          }
          tarea.setText(message);
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
 
  }
}

修改后的服務(wù)端代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package chat.chat;
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
 
/**
 * java使用socket和awt組件以及多線程簡(jiǎn)單實(shí)現(xiàn)在線聊天功能服務(wù)端 :
 * 實(shí)現(xiàn)服務(wù)端把接收到的客戶端信息轉(zhuǎn)發(fā)到所有連接的客戶端,并且讓客戶端讀取到這些信息并顯示在內(nèi)容顯示區(qū)域中。
 *
 * @author tuzongxun123
 *
 */
public class ChatServer {
 
  public static void main(String[] args) {
    new ChatServer().start();
  }
 
  // 是否成功啟動(dòng)服務(wù)端
  private boolean isStart = false;
  // 服務(wù)端socket
  private ServerSocket ss = null;
  // 客戶端socket
  private Socket socket = null;
  // 保存客戶端集合
  List<Client> clients = new ArrayList<Client>();
 
  public void start() {
    try {
      // 啟動(dòng)服務(wù)器
      ss = new ServerSocket(8888);
    } catch (BindException e) {
      System.out.println("端口已在使用中");
      // 關(guān)閉程序
      System.exit(0);
    } catch (Exception e) {
      e.printStackTrace();
    }
 
    try {
      isStart = true;
      while (isStart) {
        // 啟動(dòng)監(jiān)聽(tīng)
        socket = ss.accept();
        System.out.println("one client connect");
        // 啟動(dòng)客戶端線程
        Client client = new Client(socket);
 
        new Thread(client).start();
        clients.add(client);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 關(guān)閉服務(wù)
      try {
        ss.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
 
  }
 
  /**
   * 客戶端線程
   *
   * @author tuzongxun123
   *
   */
  private class Client implements Runnable {
    // 客戶端socket
    private Socket socket = null;
    // 客戶端輸入流
    private DataInputStream dataInputStream = null;
    // 客戶端輸出流
    private DataOutputStream dataOutputStream = null;
    private boolean isConnect = false;
 
    public Client(Socket socket) {
      this.socket = socket;
      try {
        isConnect = true;
        // 獲取客戶端輸入流
        dataInputStream = new DataInputStream(socket.getInputStream());
        // 獲取客戶端輸出流
        dataOutputStream = new DataOutputStream(
            socket.getOutputStream());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
 
    /**
     * 向客戶端群發(fā)(轉(zhuǎn)發(fā))數(shù)據(jù)
     *
     * @author:tuzongxun
     * @Title: sendMessageToClients
     * @param @param message
     * @return void
     * @date May 18, 2016 11:28:10 AM
     * @throws
     */
    public void sendMessageToClients(String message) {
      try {
        dataOutputStream.writeUTF(message);
      } catch (SocketException e) {
 
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
 
    @Override
    public void run() {
      isConnect = true;
      Client c = null;
      try {
        while (isConnect) {
          // 讀取客戶端傳遞的數(shù)據(jù)
          String message = dataInputStream.readUTF();
          System.out.println("客戶端說(shuō):" + message);
          for (int i = 0; i < clients.size(); i++) {
            c = clients.get(i);
 
            c.sendMessageToClients(message);
          }
 
        }
      } catch (EOFException e) {
        System.out.println("client closed!");
      } catch (SocketException e) {
        if (c != null) {
          clients.remove(c);
        }
        System.out.println("Client is Closed!!!!");
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        // 關(guān)閉相關(guān)資源
        try {
          if (dataInputStream != null) {
            dataInputStream.close();
          }
          if (socket != null) {
            socket.close();
            socket = null;
          }
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
 
}

就先為大家介紹到這里,之后如果有新的內(nèi)容再為大家進(jìn)行更新。

關(guān)于網(wǎng)頁(yè)在線聊天功能的實(shí)現(xiàn)大,大家還可以參考一下幾篇文章進(jìn)行學(xué)習(xí):

java實(shí)現(xiàn)一個(gè)簡(jiǎn)單TCPSocket聊天室功能分享

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家可以繼續(xù)關(guān)注服務(wù)器之家的更多精彩內(nèi)容。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 一级黄色影院 | 亚洲aⅴ免费在线观看 | 日本aaa一级片 | 国产一级免费电影 | 国产欧美日韩在线播放 | 免费在线观看成人av | 中文字幕观看 | 免费观看一区 | 久久久一二三 | 国产88久久久国产精品免费二区 | 国产精品视频免费网站 | 国产精品久久久久久久久久久久久久久 | 49vv看片免费| 久国产 | 国产一区二区三区精品在线观看 | 一区二区三区四区高清视频 | 成人国产精品一区二区毛片在线 | 欧美在线观看视频一区 | 狠狠干91| 在线看免费观看av | 九色 在线 | 蜜桃视频观看麻豆 | 久久国产精品久久精品国产演员表 | a黄毛片 | 国产精品欧美久久久久一区二区 | av免费在线播放 | 中文字幕精品一二三四五六七八 | 日韩视频在线视频 | 性高潮一级片 | 久久久久久久久国产 | 爽毛片 | 久久久国产精品网站 | 久久91精品久久久久清纯 | 亚洲精品在线观看网站 | 欧美日日操 | 嗯哈~不行好大h双性 | 精品一区二区三区免费毛片爱 | 一级观看免费完整版视频 | 黑人一区二区 | 精品成人国产在线观看男人呻吟 | 美女网站色免费 |