Socket通信小项目--大山QQ(简易版本)附源码

系统 1690 0

我是一个新手,学习了Socket通信后,寒假花了20天写了这个小项目,只有一个客户端,而且也是一个尚未完工的客户端,服务器端只用来接收,转发或保存消息。本不准备发出来的,因为项目还在编写当中,实现的功能不多,且一些细节还没有处理好,以后还会再写一个比较细致的版本,不过老师要求了,就动手写了这篇总结。

 

项目名称: 大山QQ 用以纪念我的大三

 

项目意义 :对相关知识点的一个综合练习,熟悉Java通信方面的类的用法及组件的应用,记录我大三的学习痕迹。

 

通信协议 :字节流协议

             

功能

1.注册

2.查找

3.添加/删除好友

4.添加/删除分组

5.好友上下线提醒

6.发送在线离线消息

7.发送在线离线文件

 

界面 :全部采用空布局,所有组件都是通过setBounds(....)方法添加的

 

具体流程

 

服务器端

           服务器端还没有怎么写,只实现了基本的消息传送功能。

            开启服务器以后,首先读取所有的用户信息,等待客户端的链接。由于尚未学习数据库,所有的用户信息都是

以文件形式保存的。当开启服务器后,读取的所有用户信息都保存在辅助静态类ChatTool的一个用户Map<User_ID,User>中,当客户端连接上后,若为登录消息且ID和password都正确,则将Client_Thread(服务器端的用户通信线程类)添加至ChatTool类的线程Map<User_ID,Client_Thread>中,当客户端向流中写入消息后,对应服务器通信线程读取该消息,并作出对应操作。

 

客户端

 

1.登录

            
Socket通信小项目--大山QQ(简易版本)附源码


 账号密码框只能输入10位以内的数字0到9,实现方法有两种 1.添加DocumentListener 2.添加keyListener

                                    具体见包MyComponent下的MyJTextField类

界面中的找回密码,设置只是按钮,还未添加功能。

 

若是账号密码均正确,服务器回发个人信息,包括账号,签名,头像,以及好友信息,未读消息等,建立缓存,存储好友的头像,然后转入好友列表界面。  

 

这一步有待改进,头像的字节长度远远大于其他信息的字节长度,在本机建立好友头像缓存,可以减少信息的传输,提高通信速度。 

 

 改进方法:登录前检测本机好友头像的个数,传送登录信息时加上本机好友头像的好友ID,服务器只回发其他好友的头像以及更改了头像的好友头像即可。这一步更麻烦了,不过通信效率的提升很可观。

 

 

2.注册

 

 
Socket通信小项目--大山QQ(简易版本)附源码
 

做注册界面时,重要的就是在发送注册消息前先检测输入的数据是否合法,并予以提示

 

Socket通信小项目--大山QQ(简易版本)附源码

 

当所有的信息都无误了,再向服务器发送消息。若注册成功,服务器端保存用户信息,我最开始是用一个文件保存的,

后来做其他功能时发现要修改用户信息时会很麻烦,后改为每一项信息保存为一个文件。

注册成功,回发消息,提示,返回登录界面。

 

做注册功能的时候,我意识到应该要有容错处理,一切数据都合法的情况下再提交至服务器。

 

3.好友界面


Socket通信小项目--大山QQ(简易版本)附源码
 

界面上的所有图标都是JButton,setIcon(icon),没有什么用处,主要是仿QQ,以后添加功能方便些

JTree显示好友,头像,账号,昵称,是否在线,签名

具体功能有5个

      1.添加/删除分组   2.删除好友   3.搜索用户(search)  4.双击好友头像,弹出聊天界面

 

4.用户查找界面


Socket通信小项目--大山QQ(简易版本)附源码

 

ID查找和昵称查找等的实现方法是相同的,所以就只做了一个ID查找

服务器读取要查找的用户ID,若存在就回发该用户ID,昵称等模糊查询回发的就是所有满足搜索条件的用户信息

 

当点击添加好友时,服务器接收到消息后首先检查被添加用户是否在线,在线发送消息,不在线就在被请求用户未读消息目录下的聊天消息下生成一个文件,写入消息。当被请求者用户上线时,服务器发送其信息时包含这些未读消息,同时删除未读消息文件。

 

这是另一个我觉得很重要的地方----要保证信息的不丢失

 

比如A请求添加B为好友,首先A向服务器发送请求消息,为保证B收到请求, 若B不在线,则将请求保存到B的未读文件中,在其上线时读取自身信息时(服务器在发送完温度消息后删除该消息),在通知B,若B在线则直接向其发送消息。B接收请求,选择分组,刷新界面,同时向服务器发送消息,服务器在保存信息,同时通知A结果,A在选择分组,刷新界面,再将结果发到服务器保存。

 

就是将客户端的一切改动都发到服务器保存下来。做修改个人信息的功能的时候,比如修改昵称,签名,密码等也是一样的

过程。

5.好友上下线提醒

 

 我觉得这个功能的实现是这个项目最有价值的地方。采用了观察者模式。

   具体做法如下:

   自定义一个接口MsgListener,含有方法ReceiveMsgAction(Msg msg);

 自定义一个接口subject,含有方法addMsgListener(MsgListener l),removeMsgListener(MsgListener l),

    fireMsgListener(Msg msg);

    客户端的通信线程类ClientThread继承Subject

    定义类MyJTree_AsListeber extends JTree implements MsgListener ,重载ReceiveMsgAction(Msg msg),创建对象时,将之注册到对应的通信线程上。当对应通信线程类对象调用fireMsgListener(Msg msg)时,通知JTree对象作出相应显示刷新。

 

    之前我一直都很追求外观,可当老师第一次讲到设计模式的时候,我才意识到纯粹的最求外观是没什么意义的,最重要的还是程序的结构,一个好的软件的设计应该是多种结构的综合,结构的好坏决定了程序的拓展性和可维护性。至于技术点,最好是能读懂源码,理解原理,这需要经验,现在的我还差得远,对于技术只停留在用的阶段,还未上升到理论。

 

 

6.聊天界面

 

 视频语音截图震动功能都没实现

可以修改字体属性,传送消息,文件。未保存消息


  Socket通信小项目--大山QQ(简易版本)附源码

 

 

 

 

震动的具体原理就是setLocation(x,y)方法的运用

截图,远程就是Robot类的应用

视频功能需要JMF的相关知识,还没有研究 

 

7.传送文件

 

 流程如下:1.在线文件的传送      先发送请求,对方同意后,开启一个服务器(有堵塞,应该放在线程中),回发给发送者,然后发送者连上该服务器,开启多个线程(我开启的是2个线程),分段传送文件,具体实现是RandomAccessFile类。

如DataImputStream类对象只能从文件的第一个字节开始读,但RandomAccessFile类对象可以随机读取文件,调用seek(x),或者skipBytes(X)方法,改变指针位置,就可以实现随机读取某一位置的字节。迅雷下载就是这种原理。开始,不清楚seek(x),或者skipBytes(X)方法是如何改变文件指针的,是读取X个字节再丢掉,还是直接改变指针在内存中的地址呢?经过测试,答案是后者。   2.离线文件的传送     由于只有一个通信I/o,传送文件应该另外创建Socket对象连上服务器,发送完文件后再关闭Socket。

 

 

 

 

 项目的不足

1.数据的存储    文件存储终究不如数据库存储,读取速度慢,性能低。只适合小群体的聊天

2.结构     虽然尝试使用了观察者模式,但客户端程序的耦合度还是比较高的,一个好的结构应该是多种设计模式的综合

3.功能     功能比较少,而且有缺陷,比如还没有加上远程,视频等功能,前几天已经把远程写好了,不过对图像的压缩度

              感到不满意,其他功能的细节也有待改进,比如在添加好友时,我没有先判断是否请求对象已是自身好友等,都

              是些细节的地方,还有修改个人信息的功能等等,这是都不难,但这些细节都决定着项目的友好性。很重要。

4.有一个问题没有解决,好友查找界面,表格刷新时会包空指针的错,没找到具体原因。

5.代码的结构不是很好,注解写的少了

6.没有创新       纯粹是技术的练习,尝试使用了一个设计模式,没有创新,没什么价值

 

收获

1.意识到结构和友好的重要性

2.在调试的过程中,第一次意识到Java程序对系统内存,CPU的占用问题,意识到了一些小问题,比如读写文件不关流的话,就不会释放内存。

3.让我的心情很平静,不再浮躁

 

注:项目中的所有图片都是截图截下来的,在压缩包的图片文件夹中。

Socket通信小项目--大山QQ(简易版本)附源码


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论