本文實例為大家分享了java se實現多人聊天室功能的具體代碼,供大家參考,具體內容如下
實現功能:
1.實現用戶注冊上線,下線
2.實現群聊和私聊功能
3.實現統計當前在線人數
實現思路:
1.首先,要實現服務端與客戶端之間的連接
這里是使用套接字建立tcp連接:
(1)服務器端先實例化一個描述服務器端口號的serversocket對象
(2)客戶端要創建socket對象來連接指定的服務器端
(3)服務器端調用serversocket類的accept()方法來監聽連接到服務器端的客戶端信息
(4)若服務器端與客戶端連接成功,雙方將返回一個socket對象,此時雙方可以進行通信
(5)服務器端與客戶端使用i/o流進行連接,服務端的輸出流連接客戶端的輸入流,客戶端的輸出流連接服務端的輸入流
(6)使用close()方法關閉套接字(一定要記得關閉)
2.因為是擁有一個服務端來實現多個客戶端的連接,此處還要解決的是多線程的問題。
每個客戶端需要兩個線程,來分別處理向服務端發送消息和向服務端接收消息
而服務端,當每增加一個客戶端與服務端連接,服務端都要多創建一個線程來處理與客戶端的連接
具體代碼:
單線程實現:
客戶端
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
|
import java.io.ioexception; import java.io.printstream; import java.net.socket; import java.util.scanner; /** * @author lxy * @email [email protected] * @date 2018/7/20 15:46 */ //客戶端 public class singleclient { public static void main(string[] args) throws ioexception { //客戶端連接服務器,返回套接字socket對象 socket socket = new socket( "127.0.0.1" , 6666 ); //獲取服務端的輸出流,向服務器端輸出內容 printstream printstream = new printstream(socket.getoutputstream()); printstream.println( "我是客戶端" + socket.getlocalport()); //獲取服務器端的輸入流,讀取服務器端的內容 scanner scanner = new scanner(socket.getinputstream()); scanner.usedelimiter( "\n" ); if (scanner.hasnext()) { system.out.println(scanner.next()); } //關閉流 socket.close(); } } |
服務端
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
|
import java.io.ioexception; import java.io.printstream; import java.net.serversocket; import java.net.socket; import java.util.scanner; /** * @author lxy * @email [email protected] * @date 2018/7/20 15:34 */ //服務端 public class singleserver { public static void main(string[] args) throws ioexception { //創建服務器端的serversocket對象,等待客戶端進行連接 serversocket serversocket = new serversocket( 6666 ); system.out.println( "服務器的端口號為6666,等待客戶端連接。。。" ); //偵聽并接收服務器端的連接,返回套接字socket對象 socket socket = serversocket.accept(); //獲取客戶端的輸入流,讀取客戶端的輸入內容 scanner scanner = new scanner(socket.getinputstream()); scanner.usedelimiter( "\n" ); if (scanner.hasnext()) { system.out.println( "客戶端發來消息:" + scanner.next()); } //獲取客戶端的輸出流,向客戶端輸出內容 printstream printstream = new printstream(socket.getoutputstream()); printstream.println( "客戶端你好,我是服務器端:" + serversocket.getlocalport()); //關閉流 serversocket.close(); } } |
多線程實現
客戶端
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
|
import java.io.ioexception; import java.io.printstream; import java.net.socket; import java.util.scanner; /** * @author lxy * @email [email protected] * @date 2018/7/20 15:55 */ //客戶端 //客戶端讀取服務器端信息的線程 class clientreadserver implements runnable { private socket socket; public clientreadserver(socket socket) { this .socket = socket; } public void run() { try { scanner scanner = new scanner(socket.getinputstream()); while (scanner.hasnext()) { system.out.println(scanner.next()); } socket.close(); } catch (ioexception e) { e.printstacktrace(); } } } //客戶端向服務端發送信息的線程 class clientsendserver implements runnable { private socket socket; public clientsendserver(socket socket) { this .socket = socket; } public void run() { try { printstream printstream = new printstream(socket.getoutputstream()); scanner scanner = new scanner(system.in); while ( true ) { string msg = null ; if (scanner.hasnext()) { msg = scanner.next(); printstream.println(msg); } if (msg.equals( "bye" )) { scanner.close(); printstream.close(); break ; } } } catch (ioexception e) { e.printstacktrace(); } } } public class multiclient { public static void main(string[] args) throws ioexception { socket socket = new socket( "127.0.0.1" , 6666 ); thread read = new thread( new clientreadserver(socket)); thread send = new thread( new clientsendserver(socket)); read.start(); send.start(); } } |
服務端
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
|
import java.io.ioexception; import java.io.printstream; import java.net.serversocket; import java.net.socket; import java.util.map; import java.util.scanner; import java.util.set; import java.util.concurrent.concurrenthashmap; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.regex.matcher; import java.util.regex.pattern; /** * @author lxy * @email [email protected] * @date 2018/7/20 16:12 */ class server implements runnable { private static map<string,socket> map = new concurrenthashmap<string, socket>(); private socket socket; public server(socket socket) { this .socket = socket; } public void run() { try { scanner scanner = new scanner(socket.getinputstream()); string msg = null ; while ( true ) { if (scanner.hasnextline()) { msg = scanner.nextline(); pattern pattern = pattern.compile( "\r" ); matcher matcher = pattern.matcher(msg); msg = matcher.replaceall( "" ); //用戶注冊——格式:username:用戶名 if (msg.startswith( "username:" )) { string username = msg.split( "\\:" )[ 1 ]; userregist(username,socket); continue ; } //群聊——格式:g:群聊信息 else if (msg.startswith( "g:" )) { firststep(socket); string str = msg.split( "\\:" )[ 1 ]; groupchat(socket,str); continue ; } else if (msg.startswith( "p:" ) && msg.contains( "-" )) { firststep(socket); string username = msg.split( "\\:" )[ 1 ].split( "-" )[ 0 ]; string str = msg.split( "\\:" )[ 1 ].split( "-" )[ 1 ]; privatechat(socket,username,str); continue ; } else if (msg.contains( "bye" )) { firststep(socket); userexit(socket); continue ; } else { printstream printstream = new printstream(socket.getoutputstream()); printstream.println( "格式輸入錯誤" ); continue ; } } } } catch (ioexception e) { e.printstacktrace(); } } private void firststep(socket socket) throws ioexception { set<map.entry<string,socket>> set = map.entryset(); for (map.entry<string,socket> entry:set) { if (entry.getvalue().equals(socket)) { if (entry.getvalue() == null ) { printstream printstream = new printstream(socket.getoutputstream()); printstream.println( "請先進行注冊操作!格式為:[username:用戶名]" ); } } } } private void userregist(string username, socket socket) { map.put(username,socket); system.out.println( "用戶名:" + username + "客戶端" + socket + "上線了!!" ); system.out.println( "當前在線人數為" + map.size() + "人" ); } private void groupchat(socket socket, string msg) throws ioexception { set<map.entry<string,socket>> set = map.entryset(); string username = null ; for (map.entry<string,socket> entry:set) { if (entry.getvalue().equals(socket)) { username = entry.getkey(); break ; } } for (map.entry<string,socket> entry:set) { socket client = entry.getvalue(); printstream printstream = new printstream(client.getoutputstream()); printstream.println(username + "說" + msg); } } private void privatechat(socket socket, string username, string msg) throws ioexception { string curuser = null ; set<map.entry<string,socket>> set = map.entryset(); for (map.entry<string,socket> entry:set) { if (entry.getvalue().equals(socket)) { curuser = entry.getkey(); break ; } } socket client = map.get(username); printstream printstream = new printstream(client.getoutputstream()); printstream.println(curuser + "私聊說" + msg); } private void userexit(socket socket) { string username = null ; for (string key:map.keyset()) { if (map.get(key).equals(socket)) { username = key; break ; } } map.remove(username,socket); system.out.println( "用戶" + username + "已下線" ); } } public class multiserver { public static void main(string[] args) { try { serversocket serversocket = new serversocket( 6666 ); //使用線程池 executorservice executorservice = executors.newfixedthreadpool( 20 ); for ( int i = 0 ;i < 20 ;i++) { system.out.println( "歡迎來到聊天室。。。" ); socket socket = serversocket.accept(); system.out.println( "新人加入。。。" ); executorservice.execute( new server(socket)); } executorservice.shutdown(); serversocket.close(); } catch (ioexception e) { e.printstacktrace(); } } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/L_X_Y_HH/article/details/80633819