好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

java+jdbc+mysql+socket搭建局域网聊天室

本文实现思路:利用udp协议进行 局域网 信息传输,建立点对点的聊天网络,每个端用户有自己的一个mysql数据库,所以需要获取其数据库用户名和密码,然后通过该数据库内容发送信息,接收消息则没有限制,

步骤:

建立数据表存储主机ip,接收信息端口port,nickname 向所有用户发送信息 接收信息 小部件(添加好友,删除好友)

一、建立数据表存储主机ip,接收信息端口port,nickname

在mysql数据库里建立chatusr数据表,表的格式为:

检测表是否存在和建立数据表的代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

void linkdb() {

    try {

      class .forname( "com.mysql.jdbc.driver" );

 

      conn = drivermanager.getconnection(url,user,password);

      databasemetadata dbmd=conn.getmetadata();

 

      resultset tablers = dbmd.gettables( null , null , "chatusr" , null );

 

      if (tablers.next())

        system.out.println( " the table is exsited" );

      else {

        string sql = "create table chatusr(" ; 

        sql+= " ip char(15)," ; 

        sql+= " port int(6)," ; 

        sql+= " name char(255)," ;

        sql+= "primary key(ip))" ;

        pst=conn.preparestatement(sql);

        pst.executeupdate();

      }

    } catch (sqlexception e) {

      // todo 自动生成的 catch 块

      e.printstacktrace();

    } catch (classnotfoundexception e) {

      // todo 自动生成的 catch 块

      e.printstacktrace();

    }

    system.out.println( "连接数据库成功" );

  }

二、向所有用户发送信息

向所有数据库中成员和自己发送消息;

【问题一】:string在存储中文字符时和byte[]转换时长度不一样和乱码问题
【解决方法】:用gbk标准进行转换以解决中文乱码问题,gbk标准下一个中文字符为两个char,因此可以用一个函数先计算出string转换成byte[]后的长度,再按照这个长度进行传输数据即可
【问题二】:由于udp协议中的数据报不包含用户自定义的接收信息端口,因此,我把udp传输的数据前四位设置成端口位置,每次发送信息时都会把自己的接受信息的端口加在头部,这样就能实现,当一个未知主机向我发送信息时,还能回复其信息。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

public int getlength( byte [] conf) {

     int c= 0 ,i;

     for (i= 0 ;i< 250 ;++i)

       if (conf[i]== 10 ) //'\0'的编码为10,表示数组结尾

         break ;

     return i+ 1 ;

   }

public void send(string message) {

 

       string string=m_port;

       //string+=sendcontent.gettext();

       string+=message;

       byte [] databyte = new byte [ 250 ];

       try {

         databyte=string.getbytes( "gbk" );

       } catch (unsupportedencodingexception e1) {

         // todo 自动生成的 catch 块

         e1.printstacktrace();

       }

       //string.getbytes(0, string.length(), databyte, 0);

       int len=getlength(databyte);

     //发送给自己

     try {

       datagrampacket sendpacket = new datagrampacket(databyte,len, java.net.inetaddress.getbyname(m_ip), integer.parseint(m_port));

       sendsocket= new datagramsocket();

       sendsocket.send(sendpacket);

     } catch (ioexception ioe) {

       record.append( "网络通信出现错误,问题在于" + ioe.tostring());

     }

     //发送给其他人

     for ( int ti= 0 ;ti<num;++ti) {

       try {

         datagrampacket sendpacket = new datagrampacket(databyte, len, java.net.inetaddress.getbyname(ip[ti]), integer.parseint(port[ti]));

 

         sendsocket= new datagramsocket();

         sendsocket.send(sendpacket);

       } catch (ioexception e) {

         // todo 自动生成的 catch 块

         e.printstacktrace();

       }

     }

   }

三、接收信息

接收消息时将信息和端口信息分开,若为陌生人,可以将其主机ip和端口加到数据库里,

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

public void run() {

     // todo 自动生成的方法存根

     while ( true ) {

 

       try {

         byte buf[] = new byte [ 250 ];

         receivepacket = new datagrampacket(buf, buf.length);

         receivesocket.receive(receivepacket);

         string t_ip = receivepacket.getaddress().tostring().trim();

         t_ip=t_ip.substring( 1 ); //获取ip

         string t_name= "unname" ;

         date date= new date();

         byte [] data = receivepacket.getdata();

         string receivedstring = new string(data, "gbk" );

         string t_port = receivedstring.substring( 0 , 4 ); //获取端口

         receivedstring=receivedstring.substring( 4 );

         if (t_ip.equals(m_ip)) {

           t_name=m_name;

           record.append( "来自本机:\\" + t_ip + "\n端口:" + receivepacket.getport()+ "\n时间:" + date.tostring());

           record.append( "\n" +t_name+ ":\t" );

         }

         else {

           int ti= 0 ;

           for (ti= 0 ;ti<num;++ti) {

             if (t_ip.equals(ip[ti])) {

               break ;

             }

           }

           if (ti==num) {

             mysql= "insert into chatusr values ('" +t_ip+ "','" +integer.parseint(t_port)+ "','" +t_name+ "')" ;

             if (mm.add(mysql))

               system.out.println( "插入成功" );

             t_name= "unnamed" ;

           }

           else {

             t_name=name[ti];

           }

           record.append( "\n来自主机:\\" + t_ip + "\n端口:" + receivepacket.getport()+ "\n时间:" + date.tostring());

           record.append( "\n" +t_name+ ":\t" );

         }

         record.append(receivedstring+ "\n" );

       } catch (ioexception e) {

         record.append( "网络通信出现错误,问题在于" + e.tostring());

       }

       record.selectall();

     }

   }

四、小部件

1、添加好友、删除好友
2、显示当前群聊信息

功能很简单,大家可以根据这个框架,自己完善, 代码太乱,贴一个 github链接

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/wordsin/article/details/80738878

查看更多关于java+jdbc+mysql+socket搭建局域网聊天室的详细内容...

  阅读:15次