这段小代码是因为担任Java助教给刚学习Java的本科大二的小学弟小学妹们指导,他们的实验作业就是编写一个Java聊天室客户端和服务器,为了避免出纰漏,自己事先写了一下。
客户端Ui代码:
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(); } }
客户端线程代码:
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+" "); System.out.println(s + " "); } } public void SendMessage(String text){ try{ Write.println(text); }catch(Exception e){ Println(e.toString()); } } }
服务器UI代码:
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 List<Socket> clients; //保存服务器接收到的客户端; 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(); } }
服务器线程代码:
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<Socket>(); //创建一个线程,用来等待客户端的连接; 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<this.ui.clients.size();i++){ Socket client=ui.clients.get(i); try { Write=new PrintStream(client.getOutputStream()); Write.println(s); } catch (IOException e) { Println(e.toString()); e.printStackTrace(); } } } public void Println(String s){ if(s!=null){ this.ui.Text_show.setText(this.ui.Text_show.getText()+s+" "); System.out.println(s + " "); } } } class ListenClient extends Thread{ public Server_UI ui; public Socket client; BufferedReader Read; PrintStream Write; public ListenClient(Server_UI UI,Socket Client){ this.ui=UI; this.client=Client; //创建一个接受数据的线程; new Thread(new Runnable(){ @Override public void run() { String message=""; while(true){ try { Read=new BufferedReader(new InputStreamReader(client.getInputStream())); message=Read.readLine(); Println(message); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } public void Println(String s){ if(s!=null){ this.ui.Text_show.setText(this.ui.Text_show.getText()+s+" "); System.out.println(s + " "); } } }