菜鸡的第一个与多线程,网络通讯有关的项目(极其粗糙劣质)也是第一篇博客(紧张搓手),图示中还有很多功能没实现,只有个大概的想法,博客有些乱七八糟,求各位莅临的大佬轻喷QAQ 。
本项目实现功能有:UI设计与显示(登录界面,主界面,聊天框,群聊框),QQ登录,好友文字通讯,群聊文字通讯,即时更改好友状态(好友列表,打开的聊天框,消息框),即时添加消息,服务器连接断开重连。
声明:本项目所使用图片资源大多出自github一位大佬的仿QQ项目。下面是各界面说明与效果图展示:
1. 登录界面
使用了QMovie插入动图呈现动态效果。这里初始设定是一开始登录时有初始头像,在输入账号的过程中在数据库中查找该账号,若存在该账号则会更换头像,输入密码也会通过数据库检测其正确性,检测密码正确之后连接服务器,关闭登录界面,显示QQ主界面。
2. QQ主界面
原谅其粗糙QAQ(严重质疑自己的审美),消息与联系人使用控件QTabWidget,联系人列表界面为QTreeWidget,每一个好友与群聊是一个独立的Widget。好友不在线则使用其原先头像的灰度图像表示。 在QQ主界面这里我使用了多线程技术,在用户点击登录界面登录并通过数据库判断其正确性之后,会开一条线程与服务器进行TCP连接,当成功与服务器连接,主界面显示,同时该线程会向服务器发送其个人信息,而服务器在其连接成功伊始会查询数据库及与其连接的所有客户端,将其在线的所有好友的IP地址发送回该QQ,线程接收到好友数据之后会告知主线程存储好友的IP地址并更新好友状态(这里要更新的不止好友列表状态,还要修改聊天框等的状态)。在上述操作完毕之后,线程会在固定的时间间隔向服务器发送心跳包,若服务器在固定时间内接收不到心跳包则主动断开与该客户端的TCP连接,这时线程检测到断开连接会停止发送心跳包,告知主线程QQ断线,并在固定时间间隔下不断尝试重连。
某QQ断线或下线的时候服务器也会告知所有在线好友这一消息,各QQ也会做出反应(更改好友状态等)。
3. 好友聊天框
好友通讯我也使用了多线程,并且使用UDP单播实现与好友的通讯。一开始我使用信号和槽机制接收数据,但测试结果不尽人意,经常出现丢数据现象,我就放弃了这一做法,选择开一条线程来不断检测Udpsocket的接收缓存区,若有数据则先存起来,全部数据读完再一次性发送回主线程。发送数据方面我没有开线程(考虑到同一个人同一时间也只能点一个发送吧?),点击发送的时候就将数据发送出去(好友IP地址由服务器提供,端口我设定为每一个QQ固定一个端口,存于数据库中),并在发送下一条数据之前定时重传(若是不这样做丢包率很高,不知道为啥)。这里我只实现了文字通讯。
聊天框使用QListWidget控件,每一个气泡聊天框都是一个独立Widget,插入方式与QTreeWidget类似。气泡聊天框使用PaintEvent方法绘制而成。 在接收到消息或者发送消息的时候,消息栏也会有相应变化,有记录就修改最新聊天,无记录就添加记录。 由于个人没有实现历史记录存储的功能,因此每一次登录QQ的时候消息栏都是空的。
4. 群聊聊天框
有个小毛病=-=,好友状态没整对,大概问题不大(bushi。这里我使用UDP组播实现群聊功能。在QQ主界面显示的时候就为每一个群聊建立一条线程监听固定组播地址中是否有消息传来。(开太多线程其实个人感觉不太好,只是没想到别的更好的办法),有消息传来则告知QQ并打开聊天框显示。
个人嘤嘤嘤:
这个项目做了也有半个月吧,从一开始完全不懂QT到后来能自己查阅帮助文档解决一些问题,从一开始的踌躇满志到后面一开项目就头疼,这其中经历了很多次自我否定与令人崩溃的全盘修改,虽然最后结果并没有多尽人意,但也勉强算是个项目经历了。本来感觉做得差不多了,想写篇牛逼哄哄的博客犒劳下自己,才发现原来我也没做多少功能出来,虽然实现了很多细节上的东西,但实际能用的功能也不多,说到底还是太菜了TAT,很多听起来就很牛的想法都夭折在了我有限的技术上。不能再灌输废水了!还是要振作起来,我感觉学一样东西最快的方法就是实操,不断尝试,查阅资料的过程是可以学到很多东西的,我最初是完全没有接触过QT的,对UI界面的认知还停留在大一时期接触的MFC,所以在项目伊始,设计出个登录界面都够我乐好一会,在不断尝试各个控件与查阅资料的过程中我确实学到了很多,不说熟练掌握,好歹也是了解熟悉了。
做完的时候是打算在别的电脑跑一下试试的,可是release与windeployqt打包之后在别的电脑无法连接上数据库,尝试了好几个方法都没用,只能暂时放弃了。
如果有人想了解完整的代码,可以留言。
|