杜瑞庆 李一诺
摘要:即时通讯系统在日常工作与生活中有着不可或缺的作用。文中对当下即时通讯软件的现状与痛点进行了分析,并基于此设计一款轻量化的即时通讯系统。文章使用Java语言,基于C/S架构来探究并进行系统开发,用巧妙的方法使系统突破了局域网的限制,通过系统的客户端、服务端、数据库对其设计进行了介绍,并详细阐述了系统的功能和实现步骤。
关键词:即时通讯系统;Socket;Java;文件发送;多线程;C/S
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2022)31-0029-04
1 引言
QQ、微信等即时通讯应用,早已成为了人们生活中不可或缺的部分。但历经几年的开发,其内容由于更新趋于臃肿,存储空间耗费也随着增加,且数据传递的稳定性也未能获得显著的提高,因而该类应用对于要求精简和安全的用户并不合适。
论文使用Java语言实现一款轻量化的即时通讯系统。其在保证用户基本操作的基础上,摒弃了当今即时通讯软件大部分过于臃肿的功能。信息在传输过程中会被全程加密,保证用户在沟通时的信息安全。并且基于Java语言健壮、安全、跨平台的特性,用户可以在任意操作系统上运行此系统的同时,防范各种攻击[1]。这些都对用户协同效率的提升有着重要的作用。
2 系统需求
设计一个即时通讯软件系统,要求每个用户有独立的客户端。
1) 客户端需要登录才可以进入,并带有注册页面。登录和注册页面需带有判断输入合法性的功能。
2) 用户可以通过客户端发送文本,上传文件。且接收者会实时收到消息。
3)用户可以查看消息记录,并可以下载消息记录中的文件。
3 系统设计
3.1 系统架构
程序为 C/S 架构。客户端负责信息的显示、与服务端进行消息的收发操作。服务端负责信息的收集、存储、处理、发送。
3.2 客户端设计
1) 登录与注册:系统可以判断输入是否为空、输入是否合法。对于登录功能,系统还可以判断账号是否存在、密码是否正确;对于注册功能,系统还可以判断账号或用户名是否重复、两次密码是否一致。任何错误导致无法登录或注册,系统都会清空一些已经输入的信息。
2) 消息发送:用户可以将文本写入到输入框中,点击“发送”按钮发送。也可以通过“选择文件”按钮发送文件。
3) 安全传输:信息在发送前会经过特殊加密,直至目标客户端收到才会被解密。
4) 消息接收:客户端的后台可以实时接收由服务器发送的其他用户的消息。
5) 消息显示:客户端可以在聊天框中实时显示用户本机发送的消息与其他用户的消息。
6) 消息记录查看:用户可以查看到历史的消息,即使此用户之前为离线状态。
7) 文件下载:如果消息是文件类型,用户可以将其下载到本机的任何位置。
3.3 服务端设计
1) 登录与注册:可以判断登录与注册中涉及数据库的操作。如账号是否存在,密码是否错误,用户名是否已经存在等。
2) 消息接收:实时接收任何客户端发送的消息,并存储到数据库中。若此消息是文件,系统还会将文件储存到服务器端,以供以后的下载操作。
3) 消息发送:处理收到的消息后,将消息转发到所有其他的客户端。
3.4 数据库设计
1) 数据库的概念结构设计
数据库的概念结构设计 ER 图如图1所示。
数据库的设计满足第三范式[2]。聊天平台中可以有多个用户,多条消息。每个用户可以发送多条消息,一条消息只可以来自于一个用户。
2) 数据库的逻辑结构设计
用户(用户编号,账号,用户名,密码,地址,是否在线)。
消息(消息编号,消息内容,消息类型,消息发送者id,消息接收者id,消息发送时间,文件路径)。
3) 数据库的表结构设计
3.5 通讯模型
1) 登录与注册
在对用户输入的合法性进行检测后,客户端会将注册或登录信息封装为HTTP请求并发送至服务器端,服务器端会调用数据库进一步检查数据的合法性。若数据合法,服务器会将数据存储至数据库,并将代表成功的响应发送回客户端。反之将代表失败的响应发送回客户端。客户端根据响应的成功与否决定跳转至下一步或者提醒用户重新输入。
2) 消息发送
服务器端在启动的同时会在特定端口创建一个ServerSocket来接收来自客户端的承载着消息的Socket。用户按下发送按钮后,消息类型、消息内容、发送时间、发送者和接收者等信息会被封装并通过Socket发送至服务器。当收到Socket消息后,服务器对不同类型的消息会做出不同的操作。若消息不包含文件,服务器会将消息内容等信息存入数据库。若消息包含文件,由于文件的内容过大無法存入数据库,服务器会将文件通过IO流存储到服务器本地的磁盘,由文件的存储路径代替文件的内容存入数据库。之后如果有客户端想获取文件,服务器可以通过数据库中的文件路径找到文件。
3) 消息接收
Socket可以实现不同主机之间的数据传输,但这种数据传输一般只会在同一个域中发生。各种进程使用这个相同的域互相之间用Internet协议簇来进行通信[3]。用户发送消息后需要服务器通知接收方,但由于客户端一般与服务器处于不同域,若使用Socket,服务器想要访问到客户端难度非常大。比较理想的解决方案是客户端主动向处于公网的服务器端请求,以查询是否有用户向自己发送了消息。解决方案可以根据服务端响应的时机不同分为两种:
①短轮询:客户端每隔一秒向服务器端请求一次。无论是否有消息,服务端都会做出响应。客户端根据相应的内容判断是否有新消息。
②长轮询:客户端向服务器请求,服务端会将请求挂起,直至有新消息才会响应。客户端不需要判断是否有新消息。服务端响应后,客户端会立即再发送一次请求。
如果查询到有用户向自己发送了新消息,客户端则根据消息类型的不同将消息打印至客户端。由于请求过程需要线程挂起等待,故客户端会专为消息的接收开辟一个新的线程。
4) 文件下载
文件下载请求的通讯模型较为简单。由客户端向服务端发送指定文件的下载请求,服务端收到请求后,会根据指定文件在数据库存储的文件路径找到本地的文件,并将文件转化为二进制流响应给客户端。客户端收到后会将二进制流转化为文件存储到用户指定的位置。
4 系统实现
4.1 登录与注册判断
登录与注册判断会分两步,第一步是由本地客户端判断的格式错误(输入为空、输入不合法)和服务器需要调用数据库判断的错误(登录时账号不存在、注册时用户名重复等)。只有这两步都未出现错误,登录才可以成功。
在用户点击登录或注册按钮时,客户端会扫描所有输入框体的内容,如果发现空值,则向用户提示错误。如果输入不为空,则继续判断输入是否合法。如账号密码只能由字母与数字组成,若输入不符合这一规定,则向用户提示错误。如果未发现格式错误,系统会使用Http请求将用户输入的信息发送至服务器继续判断。
服务器收到用户输入的信息后会结合数据库进行判断,并将成功与否返回至客户端。
4.2 信息的发送与接收
客户端向服务器发送数据时会根据信息类型的不同对信息做不同的封装。服务器端会收集到客户端的四种消息,格式为字符串,表示如下:
文本消息:text&发送者id&发送时间&接收者id&消息内容
文件消息:file&发送者id&发送时间&接收者id&文件名称&文件二进制编码
下载请求:download&此文件的发送者&发送时间&请求者id
历史记录请求:history&请求者id&目标用户id
服务端收到消息后会根据第一个“&”前的类型对消息做出不同的处理。
1) 文本消息
服务端通过类型text判断消息类型为文本。文本消息首先会被打印到发送者的客户端中,然后才会被发送至服务端。服务端处理完毕之后,会将信息存入到数据库,之后若接收者的客户端请求消息,服务端会从数据库中查询出消息并打包发送。客户端收到消息后会将其打印至客户端。
2) 文件消息
服务端通过类型file判断消息类型为文件。文件消息首先会被打印到发送者到客户端中。文件消息中包含文件名称和文件的二进制编码,服务端会在本地使用 IO 流创建文件并将文件的二进制编码输入实现文件的上传,最后将文件路径存储到数据库以便之后的下载操作。存储过后服务端同样会在接收者客户端请求时将消息打包发送。
3) 下载请求
用户点击文件消息中到“下载按钮”时,客户端会让用户选择文件保存路径。 选择完毕后,客户端会向服务器端发送download开头的下载请求。服务端会根据请求中包含的发送者的用户id和发送时间在数据库中查询出相应文件在服务器端的路径。找到后会将文件名和二进制编码发送给客户端,客户端收到数据后会使用 IO 流将文件保存到用户所选的路径中。
4) 消息记录查看
用户点击“历史记录”按钮时,会向服务器发送history开头的历史记录请求。服务端会查询数据库,将请求者和目标用户之间的消息全部发送。客户端处理消息后,打印至客户端的消息记录面板。
4.3 信息加密
在客户端和服务端的通讯过程中,凡是消息内容,客户端都会对其加密,直至传送到另一个客户端才会对消息进行解密并显示。系统的加密算法是基于Base64编码并融合字符串随机偏移形成的全新算法,此算法可以保证用户的数据不会泄露。
1) Base64编码
Socket有一个致命的缺陷,其不能传输汉字。想要实现汉字的传输,就要将字符串重新编码。Base64是现今最常用的编码方式之一,它可以将人们发送的信息进行特殊计算,生成一句由64个常见字符组成的字符串[4]。使用Base64编码的目的是让内容可以通过Socket在各个网关之间进行无错传输。Base64是可以编码并解码的,正因如此,它的作用主要在于数据的传输,而不是安全性。若想实现加密,需要配合字符串的变化。
2) 加密算法
Base64解码器可以解密任何以Base64加密过的字符串。但如果此字符串发生了任何微小的改变,解密结果就会大相径庭。利用此性质,客户端会对原信息进行1000次Base64加密。每两次加密之间,客户端会将字符串从中间进行分割,然后将两个字符串反转后拼接,得到一个新的字符串供下一次加密。接收者的客户端收到加密后的消息后,只需根据此算法进行1000次Base64解密便可得到消息。在未知此加密算法的情况下,暴力破解无法得到正确的结果。
5 系统测试
即时通讯系统在开发完成后,需进行系统测试,测试需要从需求符合度、功能正确性、性能指标、运行稳定性、互联互通、可用性、可维护性、兼容性等多个维度对本系统进行整体测试,并得出测试结果[5]。
系统测试过程及结果。此系统使用Java语言,由idea工具编写并对各个功能测试。1) 客户端可以完成用户的注册和登录。客户端可以判断输入格式的正确性,服务器端可以判断输入的合法性;若出现注册或登录失败,客户端会生成弹窗提醒用户。2) 用户可以发送文本消息与文件消息,在一秒钟之内目标用户可以接收到此消息。3) 用户可以下载收到的文件消息中附带的文件,下载之后文件是完整无缺的。4) 用户可以查看自己与任一用户的聊天历史。
6 结束语
本系统对当今即时通讯软件做了极致的精简,保留了用户最基本的功能。并且系统突破了局域网和系统的限制,使用户可以随时随地进行安全的信息交流和文件传送。后期会将客户端轮询的信息请求方式升级为客户端监听,这样就会大大减少服务端的负载,使其可以承担更多用户的信息交流。
参考文献:
[1] Cay S.Horstmann.Java核心技术·卷 I(原书第10版)[M].周立新,譯.北京:机械工业出版社,2016.
[2] Forta B.MySQL必知必会[M].刘晓霞,钟鸣,译.北京:人民邮电出版社,2009.
[3] 刘惠欣,孟令一.C语言从入门到精通:全新精华版[M].北京:北京希望电子出版社,2017.
[4] 石春宏.基于base64编码实现信息隐写分析[J].信息与电脑(理论版),2020,32(1):118-119.
[5] 张烜,秦庆鹏.基于Java编程语言的内网即时通讯插件系统设计与实现[J].中国新通信,2020,22(13):38-39.
【通联编辑:谢媛媛】
收稿日期:2022-05-15
作者简介:杜瑞庆(1974—) ,男,河北赞皇人,副教授,博士,主要研究方向为计算机应用、数据库应用等;李一诺(2002—) ,男,山东济南人,通信作者,本科在读,研究方向为专业软件工程。