最近做了一個(gè)項(xiàng)目,其中有一個(gè)在線網(wǎng)頁(yè)交流的需求,好久沒(méi)寫代碼了,手都生疏了,于是先寫demo練練手,分享到服務(wù)器之家平臺(tái),以此做個(gè)記錄,方便自己和大家使用。
先給大家說(shuō)下實(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
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
|
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ū)域添加回車事件 * 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)回車事件 * * @author tuzongxun123 * */ private class TFLister implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String text = tfTxt.getText().trim(); tarea.setText(text); tfTxt.setText( "" ); // 回車后發(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
|
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(); } } } } |
以上所述是小編給大家介紹的Java Socket實(shí)現(xiàn)一個(gè)簡(jiǎn)易在線聊天功能(一)的相關(guān)知識(shí),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!