好得很程序员自学网

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

java socket实现聊天室 java实现多人聊天功能

用java socket做一个聊天室,实现多人聊天的功能。看了极客学院的视频后跟着敲的。(1day)

服务端:

1. 先写服务端的类myserversocket,里面放一个监听线程,一启动就好
2. 实现服务端监听类serverlistener.java,用accept来监听,一旦有客户端连上,生成新的socket,就新建个线程实例chatsocket。启动线程后就把线程交给chatmanager管理
3. 在chatsocket中实现从客户端读取内容,把读取到的内容发给集合内所有的客户端
4. chatmanager里面用vector来管理socket线程实例chatsocket,并实现发送信息给其他的客户端

客户端:

1. 新建一个继承jframe的mainwindow.java类,主要实现聊天窗口的ui,以及事件响应。
2. 新建startclient.java类,把mainwindow中生成mainwindow主方法部分代码拷贝过来,这样就能在主程序中把窗体执行出来了。
3. 新建chatmanager(需要单例化的类)管理socket,实现聊天的输入输出功能。最后记得在1中新建窗口后,传一份frame的引用到chatmanager中,才能实现chatmanager对界面的显示。

工程结构如图

以下为代码

服务端:

1. 先写服务端的类myserversocket,里面放一个监听线程,一启动就好

?

1

2

3

4

5

6

7

8

package com.starnet.testserversocket.main;

 

 

public class myserversocket {

   public static void main(string[] args) {

     new serverlistener().start();

   }

}

2.实现服务端监听类serverlistener.java,用accept来监听,一旦有客户端连上,生成新的socket,就新建个线程实例chatsocket。启动线程后就把线程交给chatmanager管理

?

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

package com.starnet.testserversocket.main;

 

import java.io.ioexception;

import java.net.serversocket;

import java.net.socket;

 

import javax.swing.joptionpane;

 

public class serverlistener extends thread {

   public void run() {

     try {

       serversocket serversocket = new serversocket( 23456 );

       while ( true ) {

         // block

         socket socket = serversocket.accept();

         // 建立链接

         joptionpane.showmessagedialog( null , "有客户端连到本机23456端口" );

         //将socket传递给新的线程

         chatsocket cs= new chatsocket(socket);

         cs.start();

         chatmanager.getchatmanager().add(cs);

       }

     } catch (ioexception e) {

       e.printstacktrace();

     }

   }

}

3.在chatsocket中实现从客户端读取内容,把读取到的内容发给集合内所有的客户端

?

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

48

package com.starnet.testserversocket.main;

 

import java.io.bufferedreader;

import java.io.ioexception;

import java.io.inputstreamreader;

import java.io.unsupportedencodingexception;

import java.net.socket;

/*每一个连上的客户端,服务器都有一个线程为之服务*/

public class chatsocket extends thread {

   socket socket;

 

   public chatsocket(socket s) {

     this .socket = s;

   }

 

   //发送数据

   public void out(string out) {

     try {

       socket.getoutputstream().write(out.getbytes( "utf-8" ));

     } catch (unsupportedencodingexception e) {

       // todo auto-generated catch block

       e.printstacktrace();

     } catch (ioexception e) {

       // todo auto-generated catch block

       e.printstacktrace();

     }

   }

 

   //服务器会不断地从客户端读取内容,把读取到的内容发给集合内所有的客户端。

   public void run() {

     try {

       //接收数据

       bufferedreader br = new bufferedreader(

           new inputstreamreader(

               socket.getinputstream(), "utf-8" ));

       string line= null ;

       //发送读到的内容

       while ((line = br.readline())!= null ) {

         system.out.println(line);

         chatmanager.getchatmanager().publish( this , line);

       }

       br.close();

     } catch (ioexception e) {

       // todo auto-generated catch block

       e.printstacktrace();

     }

   }

}

4.chatmanager里面用vector来管理socket线程实例chatsocket,并实现发送信息给其他的客户端

?

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

package com.starnet.testserversocket.main;

 

import java.util.vector;

//一个聊天服务器只能有一个manager,要单例化处理

public class chatmanager {

   private chatmanager(){}

   private static final chatmanager cm= new chatmanager();

   public static chatmanager getchatmanager(){

     return cm;

   }

 

   vector<chatsocket> vector = new vector<chatsocket>();

   /*增加chatsocket 实例到vector中*/

   public void add(chatsocket cs){

     vector.add(cs);

   }

 

   /*发布消息给其他客户端

    *chatsocket cs: 调用publish的线程

    *msg:要发送的信息 */

   public void publish(chatsocket cs, string msg){

     for ( int i = 0 ; i < vector.size(); i++) {

       chatsocket cstemp = vector.get(i);

       if (!cs.equals(cstemp)) {

         cstemp.out(msg+ "\n" ); //不用发送给自己。

       }

     }

   }

 

}

客户端:

1. 新建一个继承jframe的mainwindow.java类,主要实现聊天窗口的ui,以及事件响应。

?

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

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

package com.starnet.javaclient.view;

 

import java.awt.borderlayout;

import java.awt.eventqueue;

 

import javax.swing.jframe;

import javax.swing.jpanel;

import javax.swing.border.emptyborder;

import javax.swing.jtextarea;

import javax.swing.grouplayout;

import javax.swing.grouplayout.alignment;

import javax.swing.jtextfield;

import javax.swing.jbutton;

import javax.swing.layoutstyle.componentplacement;

 

import com.starnet.javaclient.main.chatmanager;

import com.sun.xml.internal.ws.client.senderexception;

 

import java.awt.event.mouseadapter;

import java.awt.event.mouseevent;

 

public class mainwindow extends jframe {

 

   /**

    *

    */

   private static final long serialversionuid = 1l;

   private jpanel contentpane;

   private jtextarea txt;

   private jtextfield txtip;

   private jtextfield txtsend;

 

   /**

    * create the frame.

    */

   public mainwindow() {

     setalwaysontop( true );

     setdefaultcloseoperation(jframe.exit_on_close);

     setbounds( 100 , 100 , 450 , 300 );

     contentpane = new jpanel();

     contentpane.setborder( new emptyborder( 5 , 5 , 5 , 5 ));

     setcontentpane(contentpane);

 

     txt = new jtextarea();

     txt.settext( "ready..." );

 

     txtip = new jtextfield();

     txtip.settext( "127.0.0.1" );

     txtip.setcolumns( 10 );

 

     jbutton btnconnect = new jbutton( "connect" );

     btnconnect.addmouselistener( new mouseadapter() {

       @override

       public void mouseclicked(mouseevent e) {

         chatmanager.getchatmanager().connect(txtip.gettext());

       }

     });

 

     txtsend = new jtextfield();

     txtsend.settext( "hello" );

     txtsend.setcolumns( 10 );

 

     jbutton btnsend = new jbutton( "send" );

     btnsend.addmouselistener( new mouseadapter() {

       @override

       public void mouseclicked(mouseevent e) {

         chatmanager.getchatmanager().send(txtsend.gettext());

         appendtext( "我说: " +txtsend.gettext());

         txtsend.settext( "" );

       }

     });

     grouplayout gl_contentpane = new grouplayout(contentpane);

     gl_contentpane.sethorizontalgroup(

       gl_contentpane.createparallelgroup(alignment.leading)

         .addgroup(alignment.trailing, gl_contentpane.createsequentialgroup()

           .addgroup(gl_contentpane.createparallelgroup(alignment.trailing)

             .addgroup(gl_contentpane.createsequentialgroup()

               .addcomponent(txtsend, grouplayout.default_size, 325 , short .max_value)

               .addpreferredgap(componentplacement.related)

               .addcomponent(btnsend, grouplayout.preferred_size, 109 , grouplayout.preferred_size))

             .addgroup(alignment.leading, gl_contentpane.createsequentialgroup()

               .addcomponent(txtip, grouplayout.preferred_size, 294 , grouplayout.preferred_size)

               .addpreferredgap(componentplacement.related)

               .addcomponent(btnconnect, grouplayout.default_size, 140 , short .max_value))

             .addcomponent(txt, grouplayout.default_size, 434 , short .max_value))

           .addcontainergap())

     );

     gl_contentpane.setverticalgroup(

       gl_contentpane.createparallelgroup(alignment.leading)

         .addgroup(gl_contentpane.createsequentialgroup()

           .addgroup(gl_contentpane.createparallelgroup(alignment.baseline)

             .addcomponent(txtip, grouplayout.preferred_size, grouplayout.default_size, grouplayout.preferred_size)

             .addcomponent(btnconnect))

           .addpreferredgap(componentplacement.related)

           .addcomponent(txt, grouplayout.default_size, 198 , short .max_value)

           .addpreferredgap(componentplacement.related)

           .addgroup(gl_contentpane.createparallelgroup(alignment.trailing)

             .addcomponent(btnsend)

             .addcomponent(txtsend, grouplayout.preferred_size, grouplayout.default_size, grouplayout.preferred_size)))

     );

     contentpane.setlayout(gl_contentpane);

   }

   /*客户端发送的内容添加到中间的txt控件中*/

   public void appendtext(string in) {

     txt.append( "\n" + in);

   }

}

2.新建startclient.java类,把mainwindow中生成mainwindow主方法部分代码拷贝过来,这样就能在主程序中把窗体执行出来了。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

package com.starnet.javaclient.main;

 

import java.awt.eventqueue;

 

import com.starnet.javaclient.view.mainwindow;

 

public class startclient {

   public static void main(string[] args) {

     /*先新建一个jframe,然后把自动生成的代码贴过来*/

     eventqueue.invokelater( new runnable() {

       public void run() {

         try {

           mainwindow frame = new mainwindow();

           frame.setvisible( true );

           //创建完这个frame以后,传一份window的引用到chatmanager去

           chatmanager.getchatmanager().setwindow(frame);

         } catch (exception e) {

           e.printstacktrace();

         }

       }

     });

   }

}

3.新建chatmanager(需要单例化的类)管理socket,实现聊天的输入输出功能。最后记得在1中新建窗口后,传一份frame的引用到chatmanager中,才能实现chatmanager对界面的显示。

?

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

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

package com.starnet.javaclient.main;

 

import java.io.bufferedreader;

import java.io.ioexception;

import java.io.inputstreamreader;

import java.io.outputstreamwriter;

import java.io.printwriter;

import java.net.socket;

import java.net.unknownhostexception;

 

import com.starnet.javaclient.view.mainwindow;

 

public class chatmanager {

   private chatmanager(){}

   private static final chatmanager instance= new chatmanager();

   public static chatmanager getchatmanager(){

     return instance;

   }

   mainwindow window; //为了能在界面上显示服务器发来的信息,就需要传一个mainwindow的引用进来

   socket socket;

   private string ip;

   bufferedreader breader;

   printwriter pwriter;

   public void setwindow(mainwindow window) {

     this .window = window;

     window.appendtext( "文本框已经和chatmanager绑定了" );

   }

   public void connect(string ip) {

     this .ip = ip;

     new thread(){

 

       @override

       public void run() {

         //实现网络方法

         try {

           socket = new socket(ip, 23456 );

           //输出流

           pwriter = new printwriter(

               new outputstreamwriter(

                   socket.getoutputstream()));

           //输入流

           breader = new bufferedreader(

               new inputstreamreader(

                   socket.getinputstream()));

 

           string line = null ;

           //如果读取数据为空

           while ((line = breader.readline())!= null ) {

             window.appendtext( "收到: " +line);

           }

           //读完数据之后要关闭

           pwriter.close();

           breader.close();

           pwriter = null ;

           breader = null ;

 

         } catch (unknownhostexception e) {

           e.printstacktrace();

         } catch (ioexception e) {

           e.printstacktrace();

         }

       }

     }.start();

   }

 

   public void send(string sendmsg){

     if (pwriter!= null ) {

       pwriter.write(sendmsg+ "\n" );

       pwriter.flush();

     } else {

       window.appendtext( "当前链接已经中断..." );

     }

   }

}

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

原文链接:https://blog.csdn.net/u013427822/article/details/54947649

查看更多关于java socket实现聊天室 java实现多人聊天功能的详细内容...

  阅读:46次