本文實例為大家分享了java基于c/s結構實現多線程聊天室的具體代碼,供大家參考,具體內容如下
主要實現的功能:
服務器端建立serversocket阻塞監聽來自客戶端的socket連接,并為之開辟一個新的線程
讀取來自該連接的數據,廣播每一個客戶端數據,這里簡單地使用一個鏈表保存所有來自客戶端的所有socket連接
客戶端連接上服務器端后主要有兩個線程在工作:
主線程:不斷獲取鍵盤的輸入并寫入該socket中傳輸給服務器
副線程:不斷從服務器socket流中讀取傳來的數據,打印到屏幕上。
服務器端代碼:
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
|
import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstreamreader; import java.io.printstream; import java.net.socket; import java.net.serversocket; import java.util.arraylist; import javax.swing.joptionpane; public class myserver { public static arraylist<socket> socketlist = new arraylist<socket>(); private static string port ; public static void main(string[] args) throws ioexception { //彈出一個對話框輸入端口號 port = joptionpane.showinputdialog( "input the port number: " ); int serverport = new integer(port).intvalue(); serversocket ss = new serversocket(serverport); system.out.println( "server is initializating..." ); while ( true ) { system.out.println( "server is waiting..." ); //此處將阻塞監聽 socket s = ss.accept(); system.out.println( "listening from: " + s.getinetaddress()); socketlist.add(s); new thread( new serverthread(s)).start(); } } } class serverthread implements runnable { socket s = null ; bufferedreader br = null ; public serverthread(socket s) throws ioexception { this .s = s; br = new bufferedreader( new inputstreamreader(s.getinputstream())); } public void run() { try { string content = null ; while ( (content = readfromclient()) != null ) { //播報每個客戶端數據 for (socket s : myserver.socketlist) { printstream ps = new printstream(s.getoutputstream()); ps.println(content); } } } catch (ioexception io) { io.printstacktrace(); } } private string readfromclient() { try { return br.readline(); } catch (ioexception io) { myserver.socketlist.remove(s); system.out.println(s.getinetaddress() + " is disconnecting..." ); } return null ; } } |
客戶端代碼:
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
|
import java.net.socket; import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstreamreader; import java.io.printstream; public class myclient { public static void main(string[] args) throws exception { socket s = new socket( "192.168.1.164" , 30000 ); // new thread to read content from server. new thread( new clientthread(s)).start(); printstream ps = new printstream(s.getoutputstream()); string line = null ; bufferedreader br = new bufferedreader( new inputstreamreader(system.in)); while ((line = br.readline()) != null ) { ps.println(line); } } } class clientthread implements runnable { private socket s = null ; bufferedreader br = null ; public clientthread(socket s) throws ioexception { this .s = s; br = new bufferedreader( new inputstreamreader(s.getinputstream())); } public void run() { try { string content = null ; while ( (content = br.readline()) != null ) { system.out.println(content); } } catch (ioexception io) { io.printstacktrace(); } } } |
后期開發:
上面程序功能很簡單,沒有記錄客戶信息,考慮添加功能如下:(多人聊天室)
客戶端發來的信息必須添加特殊標識,用于區別 登陸,私聊,公聊 三種,如果是登陸,則服務器端應該有一個map來保存用戶名和對應輸出流中間的關系,用來處理用戶名重復的情況,還有如果是私聊,必須知道從客戶端發來消息的用戶名和將要發給哪一個用戶的特殊標識,考慮在輸入字符串里加入特殊標識符。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/xiaozhuaixifu/article/details/13006403