如何从零开始写一个即时通讯软件(附源码)

       即时通讯,即发送了消息后对方马上收到,一般用tcp或者udp协议来传输消息。我也是第一次深入学习tcp和udp的使用,编码过程中遇到很多难题,自己辛辛苦苦百度,解决了一个又一个困难,但是个人的听闻是有限的,希望能抛砖引玉,听取到大家更好的解决办法。

       项目地址:http://download.csdn.net/detail/qq_27311165/9911099

       首先,这个项目的服务器大部分bean用Spring来托管,Spring托管了项目的dao层和业务层(QQService)还有helper模块(UDPHelper、TCPConnectionManager这两个单例),而且都是单例。单例就可能牵扯到线程安全问题,dao都是单例,jdbc中,如果多个线程同时执行静态方法DriverManager.getConnection()会抛出异常,所以将该静态方法封装到DBHelper的getConnection()方法中,加上synchronized使线程同步,因为dao的方法除了dbHelper.getConnection();外其他都是访问局部变量和参数,每个线程调用dao的方法时都有自己的局部变量和参数,所以dao现在是线程安全的。服务器其他部分经过我不停地取证,应该也是线程安全的。             客户端,因为我想急于验证它和服务器的通讯,所以写得非常简便。客户端读者也可以用另外的语言编写,只要发送的tcp和udp报文能被服务器解析(“报文规定.txt”已经在压缩包中)。

       数据库只有3张表user、friend、unreadmsg。

CREATE TABLE user(
   userid            INT(8)            PRIMARY KEY        AUTO_INCREMENT,
   username            VARCHAR(20)    NOT NULL        unique,
   password            VARCHAR(20)    NOT NULL,
   isonline            boolean        NOT NULL,
   
    nickname        VARCHAR(20)    NOT NULL,            #昵称,网名
    sex                VARCHAR(4),
    birthday        DATE,
    hometown        VARCHAR(20),
    livein            VARCHAR(20),
    motto            VARCHAR(100)                    #座右铭,个性签名
) ;
CREATE TABLE friend(
    id                INT(20)            PRIMARY KEY        AUTO_INCREMENT,
   username            VARCHAR(20)    NOT NULL,
   friendname        VARCHAR(20)    NOT NULL,
   friendnickname        VARCHAR(20)    NOT NULL,
   fgroup            VARCHAR(20)    NOT NULL,            #好友分组名,可以一个好友一个组
   note                VARCHAR(20)        #好友备注
) ;
CREATE TABLE unreadmsg(        #只有未读消息才有资格存进数据库
    id                INT(20)            PRIMARY KEY        AUTO_INCREMENT,
   sendername        VARCHAR(20)        NOT NULL,
   receivername        VARCHAR(20)        NOT NULL,
   msgtype            int(4)            NOT NULL,
   sendtime            VARCHAR(25)        NOT NULL,            #发送者发送到服务器时,服务器把当前时间赋给它
   msg                VARCHAR(200)    NOT NULL
) ;

        先来分析一下即时通讯软件,什么数据要被存到数据库,用户的信息肯定是要存到数据库的,所以有了user表,用户肯定要有自己的好友,friend表中username是自己的用户名,后面4个字段分别表示好友用户名、好友昵称、好友所在分组名、备注名字。就这样,我们就可以用一条记录表示一个好友。最后是unreadmsg,未读消息,如果好友不在线,就先把消息存到数据库,等好友上线后,服务器从数据取出消息发给好友。

        目前服务器和客户端大部分是用tcp通信,只有发消息给好友时才用udp通信。为了方便使用tcp,客户端把Socket封装到了TCPConnection这个单例类;为了方便使用udp,客户端把Socket封装到了UDPHelper这个单例类。

         客户端可以在任何地方使用
TCPConnection.getInstance().sendAndWaitResponse(String msg);    //只往服务器发消息,且等待回应

TCPConnection.getInstance().justSend(String msg);               //只往服务器发消息,不等待回应

UDPHelper.getInstance().send(String content);                            //只往服务器发消息
发送消息给服务器。

          我突然不想写了,请自己参考其中的妙处。下载完压缩包后

请把Spring配置文件下
        <property name="dbpassword">
            <value>xxx</value>
        </property>
的xxx改为你的数据库密码
请把客户端的TCPConnection类的
    private TCPConnection() {
        try {
            client = new Socket("192.168.1.106", 8888);
            .....
"192.168.1.106"改为你服务器的ip地址,才能正常运行。

          一个路由器就是一个局域网,已经能正常运行。qq.sql脚本里创建6个默认用户。目前实现的功能:聊天、聊天记录保存(在record目录下保存)、上线未读消息提醒。请期待后续更新。

         下面是截图,一张是运行截图,一张是聊天记录文件的截图,你可能需要两台电脑登录两个账号才能开聊。(一台开启服务器和一个客户端,另一台开另一个客户端)


©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页