Java Socket實(shí)現(xiàn)多人聊天室_第1頁(yè)
Java Socket實(shí)現(xiàn)多人聊天室_第2頁(yè)
Java Socket實(shí)現(xiàn)多人聊天室_第3頁(yè)
Java Socket實(shí)現(xiàn)多人聊天室_第4頁(yè)
Java Socket實(shí)現(xiàn)多人聊天室_第5頁(yè)
已閱讀5頁(yè),還剩20頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 Java Socket實(shí)現(xiàn)多人聊天室-swing做UI標(biāo)簽: socket聊天javaexception服務(wù)器string2011-08-31 15:06 20679人閱讀 評(píng)論(25) 收藏 舉報(bào) 分類:java(21) 版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。今天翻硬盤的workspace發(fā)現(xiàn)一個(gè)Java Socket實(shí)現(xiàn)多人聊天室的源碼,不記得是什么時(shí)候的事情了,貌似不是我寫的。但寫得還不錯(cuò), 至少算個(gè)有模有樣的聊天室工具。我簡(jiǎn)單的修改了一下,拿出來(lái)跟大家分享一下,僅供參考。 

2、;         界面是用swing寫的,還不懶,簡(jiǎn)約大方。有圖有真相:   正如上圖所示,這個(gè)程序分為 服務(wù)器端和客戶端,說(shuō)白了就是 兩個(gè)main class,用eclipse直接運(yùn)行之。            聊天室的設(shè)計(jì)思想是 :在局域網(wǎng)下, 利用socket進(jìn)行連接通信,當(dāng)服務(wù)器端啟動(dòng)的時(shí)候,利用Thread線程不停的等待客戶端的鏈接;當(dāng)有客戶端開(kāi)啟連接的時(shí)候,服務(wù)器

3、端通過(guò)IO流反饋“上線用戶”信息給客戶端,客戶端也使用線程不停的接收服務(wù)器的信息,從而實(shí)現(xiàn)多人在線聊天功能。 程序中有三個(gè)類,分別 Server.java(服務(wù)器端)、Client(客戶端)、User.java(javabean)。代碼如下: Server.java(服務(wù)器端):html view plaincopy1. import java.awt.BorderLayout;  2. import java.awt.Color;  3. import java.awt.GridLayout;

4、  4. import java.awt.Toolkit;  5. import java.awt.event.ActionEvent;  6. import java.awt.event.ActionListener;  7. import java.awt.event.WindowAdapter;  8. import java.awt.event.WindowEvent;  9. import java.io.

5、BufferedReader;  10. import java.io.IOException;  11. import java.io.InputStreamReader;  12. import java.io.PrintWriter;  13. import .BindException;  14. import .ServerSocket;  15. import .Socket;  16

6、. import java.util.ArrayList;  17. import java.util.StringTokenizer;  18.   19. import javax.swing.DefaultListModel;  20. import javax.swing.JButton;  21. import javax.swing.JFrame;  22. import javax.swing.JLab

7、el;  23. import javax.swing.JList;  24. import javax.swing.JOptionPane;  25. import javax.swing.JPanel;  26. import javax.swing.JScrollPane;  27. import javax.swing.JSplitPane;  28. import javax.swing.JTextArea

8、;  29. import javax.swing.JTextField;  30. import javax.swing.border.TitledBorder;  31.   32. public class Server   33.   34.     private JFrame frame;  35.    

9、 private JTextArea contentArea;  36.     private JTextField txt_message;  37.     private JTextField txt_max;  38.     private JTextField txt_port;  39. &#

10、160;   private JButton btn_start;  40.     private JButton btn_stop;  41.     private JButton btn_send;  42.     private JPanel northPanel;  43.

11、    private JPanel southPanel;  44.     private JScrollPane rightPanel;  45.     private JScrollPane leftPanel;  46.     private JSplitPane centerSpli

12、t;  47.     private JList userList;  48.     private DefaultListModel listModel;  49.   50.     private ServerSocket serverSocket;  51.     

13、private ServerThread serverThread;  52.     private ArrayList<ClientThread> clients;  53.   54.     private boolean isStart = false;  55.   56.    &#

14、160;/ 主方法,程序執(zhí)行入口  57.     public static void main(String args)   58.         new Server();  59.       60.   61.     

15、;/ 執(zhí)行消息發(fā)送  62.     public void send()   63.         if (!isStart)   64.             JOptionPane.showMessageDialog(frame,

16、 "服務(wù)器還未啟動(dòng),不能發(fā)送消息!", "錯(cuò)誤",  65.                     JOptionPane.ERROR_MESSAGE);  66.            

17、 return;  67.           68.         if (clients.size() = 0)   69.             JOptionPane.showMessageDial

18、og(frame, "沒(méi)有用戶在線,不能發(fā)送消息!", "錯(cuò)誤",  70.                     JOptionPane.ERROR_MESSAGE);  71.          

19、0;  return;  72.           73.         String message = txt_message.getText().trim();  74.         if (message =

20、60;null | message.equals("")   75.             JOptionPane.showMessageDialog(frame, "消息不能為空!", "錯(cuò)誤",  76.           

21、;          JOptionPane.ERROR_MESSAGE);  77.             return;  78.           79.       &

22、#160; sendServerMessage(message);/ 群發(fā)服務(wù)器消息  80.         contentArea.append("服務(wù)器說(shuō):" + txt_message.getText() + "rn");  81.         txt_message.setText(n

23、ull);  82.       83.   84.     / 構(gòu)造放法  85.     public Server()   86.         frame = new JFrame("服務(wù)器"); &

24、#160;87.         / 更改JFrame的圖標(biāo):  88.         /frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png");  89.       

25、60; frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png");  90.         contentArea = new JTextArea();  91.         contentArea.se

26、tEditable(false);  92.         contentArea.setForeground(Color.blue);  93.         txt_message = new JTextField();  94.         txt_max

27、 = new JTextField("30");  95.         txt_port = new JTextField("6666");  96.         btn_start = new JButton("啟動(dòng)"); 

28、60;97.         btn_stop = new JButton("停止");  98.         btn_send = new JButton("發(fā)送");  99.         btn_stop.

29、setEnabled(false);  100.         listModel = new DefaultListModel();  101.         userList = new JList(listModel);  102.   103.    

30、60;    southPanel = new JPanel(new BorderLayout();  104.         southPanel.setBorder(new TitledBorder("寫消息");  105.         southPanel.add(txt_m

31、essage, "Center");  106.         southPanel.add(btn_send, "East");  107.         leftPanel = new JScrollPane(userList);  108.    &

32、#160;    leftPanel.setBorder(new TitledBorder("在線用戶");  109.   110.         rightPanel = new JScrollPane(contentArea);  111.         rightPa

33、nel.setBorder(new TitledBorder("消息顯示區(qū)");  112.   113.         centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,  114.          

34、0;      rightPanel);  115.         centerSplit.setDividerLocation(100);  116.         northPanel = new JPanel();  117.     &#

35、160;   northPanel.setLayout(new GridLayout(1, 6);  118.         northPanel.add(new JLabel("人數(shù)上限");  119.         northPanel.add(txt_max);  120.  

36、       northPanel.add(new JLabel("端口");  121.         northPanel.add(txt_port);  122.         northPanel.add(btn_start);  123.   &

37、#160;     northPanel.add(btn_stop);  124.         northPanel.setBorder(new TitledBorder("配置信息");  125.   126.         frame.setLayout(new BorderL

38、ayout();  127.         frame.add(northPanel, "North");  128.         frame.add(centerSplit, "Center");  129.         fra

39、me.add(southPanel, "South");  130.         frame.setSize(600, 400);  131.         /frame.setSize(Toolkit.getDefaultToolkit().getScreenSize();/設(shè)置全屏  132.    

40、;     int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  133.         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  134.    

41、;     frame.setLocation(screen_width - frame.getWidth() / 2,  135.                 (screen_height - frame.getHeight() / 2);  136.  

42、;       frame.setVisible(true);  137.   138.         / 關(guān)閉窗口時(shí)事件  139.         frame.addWindowListener(new WindowAdapter()   140. &#

43、160;           public void windowClosing(WindowEvent e)   141.                 if (isStart)   142.   

44、0;                 closeServer();/ 關(guān)閉服務(wù)器  143.                   144.       

45、0;         System.exit(0);/ 退出程序  145.               146.         );  147.   148.     

46、0;   / 文本框按回車鍵時(shí)事件  149.         txt_message.addActionListener(new ActionListener()   150.             public void actionPerformed(ActionEven

47、t e)   151.                 send();  152.               153.         ); 

48、60;154.   155.         / 單擊發(fā)送按鈕時(shí)事件  156.         btn_send.addActionListener(new ActionListener()   157.             

49、;public void actionPerformed(ActionEvent arg0)   158.                 send();  159.               160.  &

50、#160;      );  161.   162.         / 單擊啟動(dòng)服務(wù)器按鈕時(shí)事件  163.         btn_start.addActionListener(new ActionListener()   164.   

51、60;         public void actionPerformed(ActionEvent e)   165.                 if (isStart)   166.     

52、60;               JOptionPane.showMessageDialog(frame, "服務(wù)器已處于啟動(dòng)狀態(tài),不要重復(fù)啟動(dòng)!",  167.                    

53、60;        "錯(cuò)誤", JOptionPane.ERROR_MESSAGE);  168.                     return;  169.       

54、0;           170.                 int max;  171.                 int&#

55、160;port;  172.                 try   173.                     try   174.  

56、                       max = Integer.parseInt(txt_max.getText();  175.                

57、0;     catch (Exception e1)   176.                         throw new Exception("人數(shù)上限為正整數(shù)!");  177. &

58、#160;                     178.                     if (max <= 0)  &

59、#160;179.                         throw new Exception("人數(shù)上限為正整數(shù)!");  180.             

60、0;         181.                     try   182.                

61、60;        port = Integer.parseInt(txt_port.getText();  183.                      catch (Exception e1)   184.

62、                        throw new Exception("端口號(hào)為正整數(shù)!");  185.               

63、60;       186.                     if (port <= 0)   187.             

64、60;           throw new Exception("端口號(hào) 為正整數(shù)!");  188.                       189.    &

65、#160;                serverStart(max, port);  190.                     contentArea.append("服務(wù)器已成功啟動(dòng)!

66、人數(shù)上限:" + max + ",端口:" + port  191.                             + "rn");  192. &#

67、160;                   JOptionPane.showMessageDialog(frame, "服務(wù)器成功啟動(dòng)!");  193.                  

68、;   btn_start.setEnabled(false);  194.                     txt_max.setEnabled(false);  195.             &

69、#160;       txt_port.setEnabled(false);  196.                     btn_stop.setEnabled(true);  197.        

70、0;         catch (Exception exc)   198.                     JOptionPane.showMessageDialog(frame, exc.getMessage(),  

71、;199.                             "錯(cuò)誤", JOptionPane.ERROR_MESSAGE);  200.           &

72、#160;       201.               202.         );  203.   204.         / 單擊停止服務(wù)器按鈕時(shí)事件 &#

73、160;205.         btn_stop.addActionListener(new ActionListener()   206.             public void actionPerformed(ActionEvent e)   207.   

74、0;             if (!isStart)   208.                     JOptionPane.showMessageDialog(frame, "服務(wù)器還未啟動(dòng),無(wú)需停

75、止!", "錯(cuò)誤",  209.                             JOptionPane.ERROR_MESSAGE);  210.        

76、;             return;  211.                   212.               

77、  try   213.                     closeServer();  214.                   

78、60; btn_start.setEnabled(true);  215.                     txt_max.setEnabled(true);  216.               &

79、#160;     txt_port.setEnabled(true);  217.                     btn_stop.setEnabled(false);  218.          

80、0;          contentArea.append("服務(wù)器成功停止!rn");  219.                     JOptionPane.showMessageDialog(frame, "服務(wù)器成功停止!&q

81、uot;);  220.                  catch (Exception exc)   221.                     J

82、OptionPane.showMessageDialog(frame, "停止服務(wù)器發(fā)生異常!", "錯(cuò)誤",  222.                             JOptionPane.ERROR_MESSAGE);

83、60; 223.                   224.               225.         );  226.    

84、;   227.   228.     / 啟動(dòng)服務(wù)器  229.     public void serverStart(int max, int port) throws .BindException   230.         try 

85、60; 231.             clients = new ArrayList<ClientThread>();  232.             serverSocket = new ServerSocket(port);  

86、;233.             serverThread = new ServerThread(serverSocket, max);  234.             serverThread.start();  235.     

87、        isStart = true;  236.          catch (BindException e)   237.             isStart = false;&#

88、160; 238.             throw new BindException("端口號(hào)已被占用,請(qǐng)換一個(gè)!");  239.          catch (Exception e1)   240.     

89、0;       e1.printStackTrace();  241.             isStart = false;  242.             throw new BindExcepti

90、on("啟動(dòng)服務(wù)器異常!");  243.           244.       245.   246.     / 關(guān)閉服務(wù)器  247.     SuppressWarnings("deprecation")  248.

91、    public void closeServer()   249.         try   250.             if (serverThread != null)  251.   

92、60;             serverThread.stop();/ 停止服務(wù)器線程  252.   253.             for (int i = clients.size() - 1; i >

93、= 0; i-)   254.                 / 給所有在線用戶發(fā)送關(guān)閉命令  255.                 clients.get(i).getWriter().pri

94、ntln("CLOSE");  256.                 clients.get(i).getWriter().flush();  257.                 / 釋放資源

95、0; 258.                 clients.get(i).stop();/ 停止此條為客戶端服務(wù)的線程  259.                 clients.get(i).reader.close(); 

96、 260.                 clients.get(i).writer.close();  261.                 clients.get(i).socket.close();  262. 

97、60;               clients.remove(i);  263.               264.             if (se

98、rverSocket != null)   265.                 serverSocket.close();/ 關(guān)閉服務(wù)器端連接  266.               267.  

99、0;          listModel.removeAllElements();/ 清空用戶列表  268.             isStart = false;  269.          catch

100、0;(IOException e)   270.             e.printStackTrace();  271.             isStart = true;  272.      &#

101、160;    273.       274.   275.     / 群發(fā)服務(wù)器消息  276.     public void sendServerMessage(String message)   277.         

102、;for (int i = clients.size() - 1; i >= 0; i-)   278.             clients.get(i).getWriter().println("服務(wù)器:" + message + "(多人發(fā)送)");

103、60; 279.             clients.get(i).getWriter().flush();  280.           281.       282.   283.     / 服務(wù)器線程

104、60; 284.     class ServerThread extends Thread   285.         private ServerSocket serverSocket;  286.         private int max;/ 人

105、數(shù)上限  287.   288.         / 服務(wù)器線程的構(gòu)造方法  289.         public ServerThread(ServerSocket serverSocket, int max)   290.       

106、;      this.serverSocket = serverSocket;  291.             this.max = max;  292.           293.   294.  &

107、#160;      public void run()   295.             while (true) / 不停的等待客戶端的鏈接  296.              &

108、#160;  try   297.                     Socket socket = serverSocket.accept();  298.            &

109、#160;        if (clients.size() = max) / 如果已達(dá)人數(shù)上限  299.                         BufferedReader r

110、0;= new BufferedReader(  300.                                 new InputStreamReader(socket.getInputStream(); &

111、#160;301.                         PrintWriter w = new PrintWriter(socket  302.             

112、;                    .getOutputStream();  303.                         

113、;/ 接收客戶端的基本用戶信息  304.                         String inf = r.readLine();  305.           &

114、#160;             StringTokenizer st = new StringTokenizer(inf, "");  306.                    &

115、#160;    User user = new User(st.nextToken(), st.nextToken();  307.                         / 反饋連接成功信息  308. &

116、#160;                       w.println("MAX服務(wù)器:對(duì)不起," + user.getName()  309.              &#

117、160;                  + user.getIp() + ",服務(wù)器在線人數(shù)已達(dá)上限,請(qǐng)稍后嘗試連接!");  310.                  &#

118、160;      w.flush();  311.                         / 釋放資源  312.           &

119、#160;             r.close();  313.                         w.close();  314.    &

120、#160;                    socket.close();  315.                         

121、;continue;  316.                       317.                     ClientThread

122、0;client = new ClientThread(socket);  318.                     client.start();/ 開(kāi)啟對(duì)此客戶端服務(wù)的線程  319.           &

123、#160;         clients.add(client);  320.                     listModel.addElement(client.getUser().getName();/ 更新在線列表  321.  

124、                   contentArea.append(client.getUser().getName()  322.                     

125、0;       + client.getUser().getIp() + "上線!rn");  323.                  catch (IOException e)   324.    &#

126、160;                e.printStackTrace();  325.                   326.         &#

127、160;     327.           328.       329.   330.     / 為一個(gè)客戶端服務(wù)的線程  331.     class ClientThread extends Thread &

128、#160; 332.         private Socket socket;  333.         private BufferedReader reader;  334.         private PrintWriter writ

129、er;  335.         private User user;  336.   337.         public BufferedReader getReader()   338.          &#

130、160;  return reader;  339.           340.   341.         public PrintWriter getWriter()   342.          &

131、#160;  return writer;  343.           344.   345.         public User getUser()   346.           

132、60; return user;  347.           348.   349.         / 客戶端線程的構(gòu)造方法  350.         public ClientThread(Socket socket)&

133、#160;  351.             try   352.                 this.socket = socket;  353.       

134、          reader = new BufferedReader(new InputStreamReader(socket  354.                         .ge

135、tInputStream();  355.                 writer = new PrintWriter(socket.getOutputStream();  356.                

136、 / 接收客戶端的基本用戶信息  357.                 String inf = reader.readLine();  358.                 Str

137、ingTokenizer st = new StringTokenizer(inf, "");  359.                 user = new User(st.nextToken(), st.nextToken();  360.    

138、60;            / 反饋連接成功信息  361.                 writer.println(user.getName() + user.getIp() + "與服務(wù)器連接成功!"); &

139、#160;362.                 writer.flush();  363.                 / 反饋當(dāng)前在線用戶信息  364.      &#

140、160;          if (clients.size() > 0)   365.                     String temp = ""  

141、;366.                     for (int i = clients.size() - 1; i >= 0; i-)   367.          

142、               temp += (clients.get(i).getUser().getName() + "/" + clients  368.                

143、0;                .get(i).getUser().getIp()  369.                           

144、0;     + ""  370.                       371.                 

145、;    writer.println("USERLIST" + clients.size() + "" + temp);  372.                     writer.flush();  373.

146、                  374.                 / 向所有在線用戶發(fā)送該用戶上線命令  375.         

147、60;       for (int i = clients.size() - 1; i >= 0; i-)   376.                     clients.get(i).

148、getWriter().println(  377.                             "ADD" + user.getName() + user.getIp();  378.  

149、0;                  clients.get(i).getWriter().flush();  379.                   380.     &

150、#160;        catch (IOException e)   381.                 e.printStackTrace();  382.           

151、    383.           384.   385.         SuppressWarnings("deprecation")  386.         public void run() /&

152、#160;不斷接收客戶端的消息,進(jìn)行處理。  387.             String message = null;  388.             while (true)   389.     

153、            try   390.                     message = reader.readLine();/ 接收客戶端消息  391.   &

154、#160;                 if (message.equals("CLOSE")/ 下線命令  392.                     

155、60; 393.                         contentArea.append(this.getUser().getName()  394.              

156、0;                  + this.getUser().getIp() + "下線!rn");  395.                   

157、0;     / 斷開(kāi)連接釋放資源  396.                         reader.close();  397.           

158、              writer.close();  398.                         socket.close();  399.  &#

159、160;400.                         / 向所有在線用戶發(fā)送該用戶的下線命令  401.                         

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論