詳解基于java的Socket聊天程序——初始設(shè)計(jì)(附demo)
寫在前面:
可能是臨近期末了,各種課程設(shè)計(jì)接踵而來,最近在csdn上看到2個(gè)一樣問答,那就是編寫一個(gè)基于socket的聊天程序,正好最近剛用socket做了一些事,出于興趣,自己抽了幾個(gè)晚上的空閑時(shí)間敲了一個(gè),目前僅支持單聊,群聊,文件傳送這些功能。首先,貼出一個(gè)丑丑的程序圖(UI是用java swing寫的,這個(gè)早就忘光了,無奈看著JDK的API寫了一個(gè)),如下圖:

服務(wù)端設(shè)計(jì):
服務(wù)端主要有兩個(gè)操作,一是阻塞接收客戶端的socket并做響應(yīng)處理,二是檢測(cè)客戶端的心跳,如果客戶端一段時(shí)間內(nèi)沒有發(fā)送心跳則移除該客戶端,由Server創(chuàng)建ServerSocket,然后啟動(dòng)兩個(gè)線程池去處理這兩件事(newFixedThreadPool,newScheduledThreadPool),對(duì)應(yīng)的處理類分別是SocketDispatcher、SocketSchedule,其中SocketDispatcher根據(jù)socket不同的請(qǐng)求分發(fā)給不同SocketHandler去處理,而SocketWrapper則是對(duì)socket加了一層外殼包裝,用lastAliveTime記錄socket最新的交互時(shí)間,SocketHolder存儲(chǔ)當(dāng)前跟服務(wù)端交互的socket集合。設(shè)計(jì)如下:

客戶端設(shè)計(jì):
客戶端設(shè)計(jì)主要分成兩個(gè)部分,分別是socket通訊模塊設(shè)計(jì)和UI相關(guān)設(shè)計(jì)
客戶端socket通訊設(shè)計(jì),這里的設(shè)計(jì)其實(shí)跟服務(wù)端的設(shè)計(jì)差不多,不同的是服務(wù)端是接收心跳包,而客戶端是發(fā)送心跳包,由于客戶端只與一個(gè)服務(wù)端進(jìn)行通訊(客戶端之間的通訊也是由服務(wù)端進(jìn)行分發(fā)的),所以這里只使用了一個(gè)大小為2的線程池去處理這兩件事(newFixedThreadPool(2)),對(duì)應(yīng)的處理類分別是ReceiveListener、KeepAliveDog,其中ReceiveListener在初始化的時(shí)候傳入一個(gè)Callback作為客戶端收到服務(wù)端的消息的回調(diào),Callback的默認(rèn)實(shí)現(xiàn)是DefaultCallback,DefaultCallback根據(jù)不同的事件通過HF分發(fā)給不同Handler去處理,而ClientHolder則是存儲(chǔ)當(dāng)前客戶端信息,設(shè)計(jì)如下:

UI相關(guān)設(shè)計(jì),這里我不打算自己寫UI,畢竟自己寫出來的太丑了,所以后期可能會(huì)叫同學(xué)或朋友幫忙敲一下,所以我將UI的事件處理都交由Action去處理,將UI設(shè)計(jì)和事件響應(yīng)簡(jiǎn)單分離,所有UI繼承JFrame并實(shí)現(xiàn)View接口,上面的Handler實(shí)現(xiàn)類通過Router獲取(存在則直接返回,不存在則創(chuàng)建并存儲(chǔ))指定的UI,View中提供了UI的創(chuàng)建create()、獲取container()、獲取UI中的組件getComponent(),顯示display(),回收trash();ResultWrapper和ResultHolder只是為了創(chuàng)建和存儲(chǔ)聊天選項(xiàng)卡。

Common模塊設(shè)計(jì):
Common模塊主要是數(shù)據(jù)交互,這里使用JSON數(shù)據(jù)進(jìn)行交互,common模塊定義了各類交互信息,SendHelper實(shí)現(xiàn)的socket信息的傳送,I18N是語言話,ConstantValue是系統(tǒng)中的配置以及常量(這里常量都是用接口,這個(gè)可能不太好),對(duì)于ReturnMessage擁有一系列的DTO作為其content屬性。

程序入口:
最后給出服務(wù)端和客戶端的入口程序(完整代碼掛在csdn上,有時(shí)間會(huì)持續(xù)更新,文章最后有地址)
服務(wù)端入口:
package yaolin.chat.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import yaolin.chat.common.ConstantValue;
import yaolin.chat.util.LoggerUtil;
/**
* 服務(wù)器
* @author yaolin
*/
public class Server {
private final ServerSocket server;
private final ExecutorService pool;
public Server() throws IOException {
server = new ServerSocket(ConstantValue.SERVER_PORT);
pool = Executors.newFixedThreadPool(ConstantValue.MAX_POOL_SIZE);
}
public void start() {
try {
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(1);
// Watch dog. Exception??
schedule.scheduleAtFixedRate(new SocketSchedule(), 10, ConstantValue.TIME_OUT, TimeUnit.SECONDS);
while (true) {
pool.execute(new SocketDispatcher(server.accept()));
LoggerUtil.info("ACCEPT A CLIENT AT " + new Date());
}
} catch (IOException e) {
pool.shutdown();
}
}
public static void main(String[] args) {
try {
new Server().start();
} catch (IOException e) {
LoggerUtil.error("Server start failed! -> " + e.getMessage(), e);
}
}
}
客戶端入口:
package yaolin.chat.client;
import java.io.IOException;
import javax.swing.JOptionPane;
import yaolin.chat.client.callback.DefaultCallback;
import yaolin.chat.client.view.Router;
import yaolin.chat.client.view.impl.RegisterAndLoginView;
/**
*
* @author yaolin
*
*/
public class NiloayChat {
public static void main(String[] args) {
RegisterAndLoginView v = (RegisterAndLoginView) Router.getView(RegisterAndLoginView.class).create();
try {
v.display();
Client client = new Client(new DefaultCallback());
client.start();
ClientHolder.setClient(client);
} catch (IOException e) {
JOptionPane.showMessageDialog(v.getContentPane(), e.getMessage());
}
}
}
源碼下載:demo
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- java中UDP簡(jiǎn)單聊天程序?qū)嵗a
- 詳解基于java的Socket聊天程序——客戶端(附demo)
- java網(wǎng)絡(luò)編程學(xué)習(xí)java聊天程序代碼分享
- java基于TCP協(xié)議實(shí)現(xiàn)聊天程序
- java基于C/S模式實(shí)現(xiàn)聊天程序(客戶端)
- 詳解基于java的Socket聊天程序——服務(wù)端(附demo)
- java實(shí)現(xiàn)基于Tcp的socket聊天程序
- java實(shí)現(xiàn)簡(jiǎn)單TCP聊天程序
- 基于Java的Socket多客戶端Client-Server聊天程序的實(shí)現(xiàn)
- 用Java實(shí)現(xiàn)聊天程序
相關(guān)文章
Java使用百度AI接口實(shí)現(xiàn)智能機(jī)器人對(duì)話系統(tǒng)
AI已經(jīng)在各行各業(yè)中廣泛應(yīng)用,助力于各式各樣的業(yè)務(wù),而在機(jī)器人對(duì)話中,我們可以通過利用百度AI中的自然語言處理、問答知識(shí)圖譜等技術(shù),使機(jī)器人可以更加智能化、自然化的為用戶服務(wù),本文介紹Java利用百度AI接口實(shí)現(xiàn)智能機(jī)器人對(duì)話系統(tǒng)2024-01-01
SpringBoot最新定時(shí)任務(wù)的7種實(shí)現(xiàn)方案
在現(xiàn)代應(yīng)用中,定時(shí)任務(wù)是一個(gè)非常常見的需求,本文將通過7種方式講解如何在SpringBoot中實(shí)現(xiàn)定時(shí)任務(wù),包括使用@Scheduled注解、ScheduledExecutorService、Quartz、SpringTaskScheduler、Redis、XXL-JOB和Elastic-Job等,各有優(yōu)缺點(diǎn),選擇時(shí)應(yīng)根據(jù)實(shí)際需求進(jìn)行考慮2024-12-12
全面詳解java代碼重構(gòu)與設(shè)計(jì)模式
這篇文章主要為大家介紹了全面詳解java代碼重構(gòu)與設(shè)計(jì)模式的全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Array?Index?Out?of?Bounds:數(shù)組越界錯(cuò)誤解決方案及調(diào)試技巧
數(shù)組越界訪問是指訪問數(shù)組中超出其有效索引范圍的元素,這是一種常見的編程錯(cuò)誤,可能導(dǎo)致程序崩潰或數(shù)據(jù)損壞,下面這篇文章主要給大家介紹了關(guān)于Array?Index?Out?of?Bounds:數(shù)組越界錯(cuò)誤解決方案及調(diào)試技巧的相關(guān)資料,需要的朋友可以參考下2024-08-08
Java實(shí)現(xiàn)兩人五子棋游戲(三) 畫出棋子
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)兩人五子棋游戲,畫出五子棋的棋子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
Java通過導(dǎo)出超大Excel文件解決內(nèi)存溢出問題
導(dǎo)出excel是咱Java開發(fā)的必備技能,下面這篇文章主要給大家介紹了關(guān)于Java通過導(dǎo)出超大Excel文件解決內(nèi)存溢出問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
java計(jì)算自然數(shù)中的水仙花數(shù)的方法分享
這篇文章主要介紹了java計(jì)算自然數(shù)中的水仙花數(shù)的方法,需要的朋友可以參考下2014-03-03

