这段小代码是因为担任Java助教给刚学习Java的本科大二的小学弟小学妹们指导,他们的实验作业就是编写一个Java聊天室客户端和服务器,为了避免出纰漏,自己事先写了一下。
客户端Ui代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
package com.CS;import java.awt.BorderLayout;import java.awt.FlowLayout;import java.awt.GridBagLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;public class Client_UI extends JFrame{ public JButton Connect; //创建连接按钮; public JButton Say; //创建发送按钮; public JPanel Panel; //创建一个用于存放所有组件的容器; public JPanel Panel_up; //创建一个用于存放界面最上面各个组件的容器; public JPanel Panel_down; //创建一个用于存放界面最下面各个组件的容器; public JTextField Server_IP; //用于写IP地址的组件; public JTextField Server_Port; //用于写端口号的组件; public JTextField Say_Send; //用于写要发送的文字的内容的组件; public JTextArea Text_Show; //用于显示相关信息的组件; public Client_Thread Server; //创建一个客户端线程; public Client_UI(){ Connect=new JButton("Connect"); Say=new JButton("Say"); Server_IP=new JTextField(10); Server_Port=new JTextField(5); Say_Send=new JTextField(25); Text_Show=new JTextArea(); JScrollPane ScrollPane=new JScrollPane(); //使之可以滚动,且设置滚动一直存在; ScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); ScrollPane.setViewportView(Text_Show); Panel_up=new JPanel();// Panel_up.setLayout(new GridLayout(1,5));// Panel_up.setLayout(new FlowLayout(FlowLayout.LEFT)); Panel_up.setLayout(new GridBagLayout()); //布局方法,调试得出该布局方法最合理; Panel_up.add(new JLabel("Server IP")); Panel_up.add(Server_IP); Panel_up.add(new JLabel("Server Port")); Panel_up.add(Server_Port); Panel_up.add(Connect); Panel_down=new JPanel();// Panel_down.setLayout(new GridLayout(1,3)); Panel_down.setLayout(new FlowLayout(FlowLayout.LEFT)); //布局方法,调试得知,从左边最先开始存放组件。 Panel_down.add(new JLabel("Say")); Panel_down.add(Say_Send); Panel_down.add(Say); Panel=new JPanel(); Panel.setLayout(new BorderLayout()); Panel.add(Panel_up, BorderLayout.NORTH); Panel.add(ScrollPane); Panel.add(Panel_down,BorderLayout.SOUTH); this.setTitle("客户端"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setLocation(600, 200); this.add(Panel); this.setVisible(true); //对connect按钮增加监听; Connect.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { Server=new Client_Thread(Client_UI.this); } }); //对Say按钮增加监听; Say.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { Server.SendMessage(Say_Send.getText()); Say_Send.setText(""); } }); } public static void main(String args[]){ Client_UI clientui=new Client_UI(); }}
客户端线程代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
package com.CS;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;//import java.io.PrintWriter;import java.net.Socket;public class Client_Thread extends Thread { Client_UI UI; Socket client_socket; BufferedReader Read; PrintStream Write; public Client_Thread(Client_UI ui){ this.UI=ui; String IP=UI.Server_IP.getText().trim(); //获取IP地址; int Port=Integer.parseInt(UI.Server_Port.getText().trim()); //获取端口号,并将其转换成int型; try { client_socket=new Socket(IP,Port); //设置连接服务器的IP地址和端口号; Println("客户端连接服务器成功!"); Read=new BufferedReader(new InputStreamReader(client_socket.getInputStream())); Write=new PrintStream(client_socket.getOutputStream()); } catch (IOException e) { Println("客户端连接服务器失败!"); e.printStackTrace(); } new Thread(new Runnable(){ @Override public void run() { String message=""; while(true){ try { message=Read.readLine(); } catch (IOException e) { Println("连接服务器中断!"); e.printStackTrace(); break; } if(message!=null&&message.trim()!=""){ Println(message); } } } }).start(); } public void Println(String s){ if(s!=null){ this.UI.Text_Show.setText(this.UI.Text_Show.getText()+s+"\n"); System.out.println(s + "\n"); } } public void SendMessage(String text){ try{ Write.println(text); }catch(Exception e){ Println(e.toString()); } }}
服务器UI代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
package com.Server;import java.awt.BorderLayout;import java.awt.FlowLayout;import java.net.Socket;import java.util.List;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;public class Server_UI extends JFrame{ public JButton Start; public JButton Say; public JTextField Port_Msg; public JTextField Say_Msg; public JPanel Panel_up; public JPanel Panel; public JPanel Panel_down; public JTextArea Text_show; public Server server; public Listclients; //保存服务器接收到的客户端; public Server_UI(){ Start=new JButton("Start"); Say=new JButton("Say"); Port_Msg=new JTextField(25); Say_Msg=new JTextField(25); Text_show=new JTextArea(); JScrollPane ScrollPane=new JScrollPane(); ScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); ScrollPane.setViewportView(Text_show); Panel_up=new JPanel(); Panel_up.setLayout(new FlowLayout()); Panel_up.add(new JLabel("Port")); Panel_up.add(Port_Msg); Panel_up.add(Start); Panel_down=new JPanel(); Panel_down.setLayout(new FlowLayout()); Panel_down.add(new JLabel("Say")); Panel_down.add(Say_Msg); Panel_down.add(Say); Panel=new JPanel(); Panel.setLayout(new BorderLayout()); Panel.add(Panel_up, BorderLayout.NORTH); Panel.add(ScrollPane,BorderLayout.CENTER); Panel.add(Panel_down,BorderLayout.SOUTH); this.setTitle("服务器"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setLocation(100, 200); this.add(Panel); this.setVisible(true); //设置Start监听器; Start.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { server=new Server(Server_UI.this); } }); //设置Say监听器; Say.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { server.Send_Message(Say_Msg.getText()); Say_Msg.setText(""); } }); } public static void main(String args[]){ Server_UI serverUI=new Server_UI(); }}
服务器线程代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
package com.Server;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;public class Server extends Thread{ Server_UI ui; BufferedReader Read; PrintStream Write; ServerSocket server; public Server(Server_UI UI){ this.ui=UI; //设置服务器的端口; int port=Integer.parseInt(ui.Port_Msg.getText().trim()); try { server=new ServerSocket(port); Println("端口设置成功!"); } catch (IOException e) { Println("端口设置失败!"); e.printStackTrace(); } this.ui.clients=new ArrayList(); //创建一个线程,用来等待客户端的连接; new Thread(new Runnable(){ @Override public void run() { while(true){ Println("等待客户端接入..."); Socket Client = null; try { Client = server.accept(); ui.clients.add(Client); Println("成功连接到客户端"+Client.toString()); new ListenClient(ui,Client); } catch (IOException e) { Println("连接客户端失败!"); Println(Client.toString()); e.printStackTrace(); } } } }).start(); } public synchronized void Send_Message(String s){ for(int i=0;i