Skip to content

iDTer/ChatRoom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

ChatRoom

本网络聊天程序系统分为服务器端和客户端。

服务器端的面板上中央为一个展示在线聊天人员名称的JList列表,可被选中,界面的下部分整齐排列着一个JTextFile输入文本窗口和一个“群发消息”和一个“踢出群聊”的按钮。可实现群聊中服务器群发消息,和服务器将人踢出群聊的功能。

打开聊天室客户端,弹出输入昵称的窗口,昵称可输入中文,然后进入聊天的界面,左侧为一个用户列表,实时更新在线用户,右侧为聊天记录区,上方是一个文本输入框,下方整齐排列着两个按钮,分别为“发送消息”、“私聊”。

关键问题设计

1.服务器端(2个类:Server主类,ChatThread类):

1)、Server类:

(1)Server的构造函数:

设置“服务器端”为窗口标题,设置好界面,具体见源码。

(2)run函数:

由于主类实现了Runnable接口,新开的线程一直在9999端口扫描等待,若accept一个来客户端的Socket,就新建一个ChatThread,并将此线程加入ChatThread类型的ArrayList中,方便管理聊天线程。

对于刚刚登陆的用户,它的本地是没有用户在线信息的,于是向他发送JList里的用户登陆信息。

(3)actionPerformed函数:

​ 由于主类实现了ActionListener接口,通过比对按键的不同实现不同的功能。

(4)handleAll函数:

​ 当监听到对“群发消息”按钮的点击时,调用此函数,在输入框内文本不为空的情况下,将文本框输入的文本以“ALL#”为前缀发给所有在线程列表中的客户端,并把文本框清空。实现服务器的群发功能。

(5)handleExpel函数:

​ 当监听到“踢出聊天室”按钮的点击时,调用此函数,users.get(userList.getAnchorSelectionIndex()).s.close();首先用getAnchorSelectionIndex()返回在装有在线用户名称的JList中得到被选中的序号,ArrayList类型的users使用get方法得到这个索引号下的ChatThread然后得到它的Socket并将其关闭。通过向所有的客户端以“OFLINE#”为前缀加上被选择的用户昵称,然后在服务器端的用来存放所有在线用户的默认字符串型模板的列表里删除掉此昵称的用户,通过userList.repaint();的方式更新列表显示。

(6)sendMessage函数:

​ 调用时传入一个字符串类型的参数,将其发送给所有的在线程列表中的客户端。

2)、ChatThread类:

​ 继承Thread类,搭建好用来与服务器传输信息的BufferedReader和PrintStream,br相当于听筒用来接收来自客户端的消息,ps相当于话筒,用来将消息发送给指定的客户端。

(1) ChatThread构造函数: 传入参数为Socket

(2) run函数: 此线程用来一直等待接受来自各服务器的消息,并用“#”将得到的消息分划开,从而进一步判断具体操作: LOGIN——对应着用户登陆信息,取出消息中用户发来的昵称,加入用户列表,然后将此登陆信息发送给所有的客户端,以便更新在线用户列表,同时提示好友的上线。

MSG||SMSG||FSMSG——分别是用户群聊消息,私聊消息和第一次私聊消息的标识符,此时立即将此消息转发给所有客户端,不做任何处理。

OFLINE——收到来自客户端的下线消息,转发给所有客户端,用以更新在线列表,并在服务器列表中删除此用户。更新列表。

2. 客户端(一个Cilent主类):

(1)Client构造函数:

​ 具体界面设计见源码,当用户登陆时,输入昵称,以“LOGIN#”加昵称的形式发送给服务器端。由于主类实现了ActionListener接口,且在输入框绑定了一个KeyListener,用于实现按回车键时将输入框的消息发送出去。为此,还需要将输入框设置为被聚焦。又为窗口增加了一个WindowListener,用以实现在窗口关闭用户退出时实时更新在线用户列表,以“OFLINE#”加昵称的形式将消息发送给服务器端。

(2)run函数:

一直在循环接受来自服务器端的消息,首先将得到的消息用“#”划分为字符串数组。通过判断字符串数组第一个标识符,来决定进一步操作。

​ LOGIN——取出字符串数组中的用户昵称,判断若不为自己的登陆昵称,则在聊天记录中显示,某某某上线了!并在在线用户列表中增加此昵称,更新列表。

​ MSG——判断若昵称为自己则在聊天记录显示“我说”+ 消息,若并非自己,则取出发信人昵称,显示“用户名”+ 消息。

​ USERS——为实时更新在线用户列表的一则信息,在后来用户加入群聊或群聊中有新用户上线时,收到此消息,加入到用户列表中,由于列表数据结构中反复添加同一名称,列表中仍只存在一个此名称的特性。

​ ALL——服务器端发来的全体消息,客户端收到此消息,以“全体消息:”+消息的格式显示在聊天记录上

​ OFLINE——服务器踢人或用户下线时的消息,用以提示客户端更新在线用户列表。

​ (strs[2].equals(nickName) || strs[1].equals(nickName)) && strs[0].equals("SMSG")满足此条件时,表示此为涉及到自己的私聊消息,进行进一步操作,若消息昵称为自己,则在私聊聊天面板中添加“我说:”+消息,否则添加“某某说:”+消息。

​ (strs[2].equals(nickName) || strs[1].equals(nickName))&& strs[0].equals("FSMSG")满足此条件时,表示此为涉及到自己的第一次私聊消息,与之后不同的是,若自己是收信人,则在主面板显示“某某私信了你”提示用户点击查看私聊消息。

(3) actionPerformed函数:

判断点击按钮,若点击的为“发送消息”,则调用handleSend函数,若点击的是“私发消息”,则调用handleSec函数,若为在私聊窗口中点击“发消息”按钮,则调用handleSS函数。

(4) handleSend函数:

以“MSG#”加消息的格式将输入框中的消息发送给服务器。

(5) handleSS函数:

判断是否为第一次与某人私发消息,若是,则以“FSMSG#”+ 消息的格式发送,否则以“SMSG#”+ 消息的格式发送。

(6) handleSec函数:

新建一个与选中用户私聊的窗口,具体见源代码。

3. 截图

服务器端界面:

png

客户端界面:

png

png

png

群聊列表:

png

png

About

Java网络编程 多人聊天室

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages