socket(java) 搭建一個多人在線聊天室



說明

今年因爲疫情緣由只能在家裏學習,今年學校有一門很重要的課程《面向對象》,學習了java中的編程思想、多線程、JML、UML等等東西,爲了檢驗本身學習得好很差,再加上據說 java 很適合 socket 編程,而且阿里雲的服務器一年才九十多塊錢,我就決定(其實以上都不是主要緣由,主要緣由就是考完試在家閒的發慌)決定搭建一個多人在線聊天室,而且從中也能夠學習 Swing、socket 等等。java

後面代碼中全部GUI界面佈局的內容,參見我以前的一篇博客 Swing的簡要學習記錄git

本次實現的聊天室功能比較簡單,主要實現的功能以下:github

  • 帶有優美的 GUI界面(纔怪);
  • 在服務器容許的壓力下支持多人實時聊天;
  • 支持帳戶登陸功能(不支持註冊功能,也就是服務器端預先設好了帳號)

如下是或許下一次要改進的內容:編程

  • 實現註冊功能;
  • 實現單人聊天;
  • 實現好友功能


Socket及java編程方法

socket(套接字)是計算機之間進行通訊的一種約定。若是學過操做系統應該會知道,進程之間的通訊(IPC)包括管道、FIFO、共享內存、信號量機制等等,這裏socket就是一種可用於不一樣計算機的進程之間的通訊機制,用來解決網絡通訊問題。服務器

socket的通訊基於TCP/IP協議,用(ip地址,協議,端口號)惟一標識某一個主機中的某一個進程,socket通訊的數據傳輸方式包括兩種:SOCK_STREAM(流套接字,基於TCP協議,特色是不易出錯)和SOCK_DGRAM(數據報套接字,基於UDP協議,特色是速度快)。java中的socket編程應該主要是基於TCP協議的。TCP鏈接時有什麼三次握手創建鏈接(connect)、四次握手斷開鏈接(close),這些說實話具體過程我都不瞭解。網絡

我只知道 java 中應該怎麼寫(注意裏面的Macro是我本身定義的一個類,能夠忽略):多線程

  • 服務器端:
// 創建socket服務
ServerSocket serverSocket = new ServerSocket(Macro.port);
// 這句話的意思是,一直等待客戶端鏈接,一旦鏈接成功就返回一個socket
Socket socket = serverSocket.accept();

主要的socket鏈接創建其實就這兩個,通常實現時會每當有客戶端鏈接時,新建一個線程去處理。socket

  • 客戶端:
// 創建一個與serverIP服務器,port端口的socket鏈接
try {
    socket = new Socket(Macro.serverIp, Macro.port);
} catch (Exception e) {
    e.printStackTrace();
}

就這樣服務器和客戶端的socket鏈接就如此方便地創建好了!函數

  • 經常使用文件流:
BufferedReader bufferedReader = null;	// 這個是socket中的輸入流
PrintWriter printWriter = null;			// 這個是socket中的輸出流
try {
	bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
	printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (Exception e) {
	e.printStackTrace();
}

這些文件流跟本地的標準輸入輸出以及文件操做其實差很少,就是寫入讀出這些操做。佈局

而後就能夠服務器和客戶端就能夠經過這兩個流進行通訊了。



功能結構

共享類

這是服務器和客戶端共享的類,這些類無論在打包服務器的jar或者客戶端的jar時都應該包括在內,這些類包括Macro和Message,前者定義了一些通訊中encode和decode的規則,以及服務器ip、端口號等等,後者用於雙方發送消息的載體。

  • Macro類:定義通訊規則(包括對LOGIN請求的加密和解密、LOGOUT請求的加密和解密、MESSAGE的加密和解密、登陸是否成功信號的定義)、服務器相關信息、一些信號的宏定義等等;
  • Message類:定義了用戶發送的一個message須要包含的信息,有:發送者、發送時間、發送內容。
服務器端

服務器端處理用戶登陸登出請求、維護當前登陸狀態、維護用戶帳號密碼信息、處理message發送請求,而且要支持多用戶服務,主要包含的類以下:

  • server類:一直運行,初始加載Info類和MessageSend類,而且一直調用serverSocket.accept()進行socket鏈接監聽,一但有socket鏈接成功,新建一個serverThread線程進行socket通訊。
  • serverThread類:這個類與Info類和MessageSend類有關聯關係,用於與socket通訊。這個類須要一直讀入用戶請求,而且支持三種請求:
    • LOGIN請求:經過Info類判斷該用戶是否合法,密碼是否正確,若是正確就在MessageSend中設定該用戶在線,而且經過socket返回登陸成功信號;
    • LOGOUT請求:直接在MessageSend中設定該用戶註銷(不在線);
    • MESSAGE請求:MessageSend中調用函數,給全部在線用戶發送該message。
  • Info類:記錄用戶帳號密碼信息,提供帳號密碼是否正確的服務。
  • MessageSend類:記錄在線用戶(username)以及與他們socket通訊中的PrintWriter,實現發送Message的功能。
客戶端

客戶端用於用戶登陸以及聊天,主要實現了兩個GUI界面(登陸界面和聊天界面),包括的類以下:

  • Client類:調用登陸界面。
  • Login類:實現登陸界面的JFrame,與服務器創建鏈接,每當進行登陸操做時向服務器發送登陸請求,而後讀取登陸是否成功的信息,若是成功調用Dialog類運行而且向之傳送socket信息,而後銷燬本身。
  • Dialog類:實現聊天界面的JFrame,經過socket與服務器通訊,每當進行發送操做時,打包輸入框中的文字爲Message,而後發送給服務器。而且一直讀入服務器傳來的數據,進行decode而後顯示在聊天框中。還要對窗體的關閉鍵進行監聽,關閉窗體時向服務器發送LOGOUT請求,而且關閉當前的socket,而後銷燬本身。


效果展現



代碼

詳細的代碼和運行方法,參見 這裏

相關文章
相關標籤/搜索