登录界面的用户名和端口号不能重复!
登录界面的用户名和端口号不能重复!
登录界面的用户名和端口号不能重复!
java的socket编写的聊天室,GUI的界面,可以私聊和群聊,
聊天信息保存为txt
有需要的可以自行下载,可以先观看教学视频再决定是否购买
下载链接:
https://download.csdn.net/download/qq_52889967/20065491
教学视频:
https://v.qq.com/x/page/u3258g37y8s.html
java学生成绩管理系统(GUI界面):
https://blog.csdn.net/qq_52889967/article/details/118581246
运行结果:
保存结果:在D盘
“D:\私聊记录.txt”
“D:\群聊记录.txt”
部分源代码展示:
部分源代码如下:
服务端:
package myproject;import java.awt.Font;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;public class UI {// 定义文本区public static JTextArea text_area=new JTextArea();
// 定义存储从客户端接受到的客户用户名、IP和端口号public static ArrayList<String> all_userArrayList=new ArrayList<String>();public static ArrayList<String> all_userArrayList_IP=new ArrayList<String>();public static ArrayList<String> all_userArrayList_Port=new ArrayList<String>();// 定义存储客户端IP的Stringpublic static String IP =null;public static void main(String[] args) {// TODO Auto-generated method stubUI ui=new UI();ui.init_1();}// 定义服务器界面public void init_1() {
// 定义窗口JFrame jframe_1=new JFrame("服务器");// 服务器关闭时,保存分割线(防止不同的txt保存混在一起)jframe_1.addWindowListener(new WindowListener() {@Overridepublic void windowOpened(WindowEvent e) {}@Overridepublic void windowClosing(WindowEvent e) {// 此处加入操作动作
// 保存群聊的分割线Save.save_1("-----------分割线-----------", "-----------分割线-----------");
// 保存私聊的分割线Save.save_2("-----------分割线-----------", "-----------分割线-----------",null);}@Overridepublic void windowClosed(WindowEvent e) {}@Overridepublic void windowIconified(WindowEvent e) {}@Overridepublic void windowDeiconified(WindowEvent e) {}@Overridepublic void windowActivated(WindowEvent e) {}@Overridepublic void windowDeactivated(WindowEvent e) {}});// 设置窗口大小jframe_1.setSize(400,400);
// 窗口不能调整jframe_1.setResizable(false);
// 空布局jframe_1.setLayout(null);
// 退出则关闭程序jframe_1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 定义按钮JButton jbutton_1=new JButton("开启服务器");
// 设置按钮位置和大小jbutton_1.setBounds(130,0,130,40);
// 将按钮添加到窗口jframe_1.add(jbutton_1);// 设置文本区位置和大小text_area.setBounds(0,50,385,310);
// 设置文本区不可编辑text_area.setEditable(false);
// 定义滚动面板JScrollPane sp_3=new JScrollPane(text_area);sp_3.setLocation(0,50);sp_3.setSize(385,310);
// 定义字体Font font=new Font("宋体",Font.BOLD,16);sp_3.setFont(font);jframe_1.add(sp_3);// 注册开启服务器按钮的监听EventListener e=new EventListener(jbutton_1);jbutton_1.addActionListener(e);
// 窗口居中jframe_1.setLocationRelativeTo(null);
// 显示窗口jframe_1.setVisible(true); }}
package myproject;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;import javax.swing.JOptionPane;// 开启服务器的server(多线程)
// 每个客户端与服务器连接后,都会将自己的用户名和端口号发送过来(只接收客户端用户名、IP和端口号)
public class Server_1 extends Thread {public static ServerSocket server_1=null;public static Socket socket_1=null;
// 定义输入流,用于接收客户端发送的消息public static InputStream input_1=null;public static DataInputStream dinput_1=null;
// 定义字符串用于暂时存储信息String s=null;//启动线程的方法public void run() {
// 死循环,当有客户端连接时,循环等待下一个客户端while(true) {
// 异常捕获try {
// 开放2021端口server_1=new ServerSocket(2021);
// 调用获取socket方法,等待连接socket_1=server_1.accept();
// 获取输入流input_1=socket_1.getInputStream();dinput_1=new DataInputStream(input_1);// 读取用户名并添加s =dinput_1.readUTF();UI.all_userArrayList.add(s);// 读取IPUI.IP=dinput_1.readUTF();
// 处理接收到的IP,接收的IP格式为主机名/ip,我们只需要后面的部分(通过正则表达式匹配数据)String str[]=UI.IP.split("/");
// str[1]为我们需要的数据UI.IP=str[1];UI.all_userArrayList_IP.add(UI.IP);
// System.out.println("IP:"+UI.all_userArrayList_IP);// 读取端口号并添加UI.all_userArrayList_Port.add(dinput_1.readUTF());
// System.out.println("端口号:"+UI.all_userArrayList_Port);
// 提示用户上线UI.text_area.append("用户->"+s+" 上线了!\n");}catch (Exception e) {System.out.println(e);JOptionPane.showMessageDialog(null, "Server_1服务器异常!!!","错误提示",JOptionPane.WARNING_MESSAGE);break;}finally {if(dinput_1!=null) {try {dinput_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(input_1!=null) {try {input_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(socket_1!=null) {try {socket_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(server_1!=null) {try {server_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}} }
}
package myproject;import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;import javax.swing.JOptionPane;//只用于将当前在线人数传递到客户端
public class Server_3 extends Thread {public static ServerSocket server_1=null;public static Socket socket_1=null;
// 定义输出流public static OutputStream output_1=null;public static DataOutputStream doutput_1=null;//启动线程的方法public void run() {
// 死循环,当有客户端连接时,循环等待下一个客户端while(true) {
// 异常捕获try {
// 开放2023端口server_1=new ServerSocket(2023);
// 调用获取socket方法,等待连接socket_1=server_1.accept();
// 获取输出流output_1=socket_1.getOutputStream();doutput_1=new DataOutputStream(output_1);
// 发送用户数量doutput_1.writeUTF(""+UI.all_userArrayList.size());
// 发送用户名for(int i=0;i<UI.all_userArrayList.size();i++) {doutput_1.writeUTF(UI.all_userArrayList.get(i));
// System.out.println(UI.all_userArrayList);}
// System.out.println(UI.all_userArrayList.size());
// System.out.println("服务端:"+UI.all_userArrayList);}catch (Exception e) {System.out.println(e);JOptionPane.showMessageDialog(null, "Server_3服务器异常!!!","错误提示",JOptionPane.WARNING_MESSAGE);break;}finally {if(doutput_1!=null) {try {doutput_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(output_1!=null) {try {output_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(socket_1!=null) {try {socket_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(server_1!=null) {try {server_1.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}} }
}
客户端:
package myproject;import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.util.ArrayList;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 UI {
// 窗口public static JFrame jframe_1 = new JFrame("聊天小程序");
// 定义容器public static JFrame jframe_2=new JFrame("登录");
// 设置面板public static JPanel p_1 = new JPanel(null);public static JPanel p_2 = new JPanel(null);public static JPanel p_3 = new JPanel(null);
// 按钮public static JButton jbutton_1 = new JButton("发送");
// 文本框public static JTextField text_1 = new JTextField();
// 文本区public static JTextArea text_area_1 = new JTextArea();public static JTextArea text_area_2 = new JTextArea();
// 注册用户名public static String user;
// 定义从客户端接受到的客户用户名,用于私聊展示public static ArrayList<String> all_userArrayList=new ArrayList<String>();public static void main(String[] args) {UI ui = new UI();ui.init();}// 登录界面public void init() {
// 流式布局jframe_2.setLayout(new FlowLayout());
// 设置窗口大小jframe_2.setSize(250,150);
// 居中显示jframe_2.setLocationRelativeTo(null);
// 退出后程序结束jframe_2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 定义标签JLabel l_1=new JLabel("用户名: ");JLabel l_2=new JLabel("服务器IP: ");
// 定义字体(宋体,加粗)Font font_1=new Font("宋体",Font.BOLD,20);l_1.setFont(font_1);l_2.setFont(font_1);
// 定义文本框JTextField text_2=new JTextField(10);JTextField text_3=new JTextField(10);text_2.setText("192.168.1.3");
// 定义按钮JButton jbutton_2=new JButton("注册并登录");jframe_2.add(l_2);jframe_2.add(text_2);jframe_2.add(l_1);jframe_2.add(text_3);jframe_2.add(jbutton_2);
// 注册监听EventListener_1 e_2=new EventListener_1(text_2,text_3);jbutton_2.addActionListener(e_2);
// 显示窗口jframe_2.setVisible(true);}// 主界面public static void init_1() {
// 空布局jframe_1.setLayout(null);;
// 窗口大小jframe_1.setSize(600,400);
// 窗口居中jframe_1.setLocationRelativeTo(null);
// 窗口不能调整jframe_1.setResizable(false);
// 退出后程序结束jframe_1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置面板p_1.setLocation(0,0);p_2.setLocation(320,0);p_3.setLocation(0,300);p_1.setSize(280,280);p_2.setSize(280,400);p_3.setSize(280,100);p_2.setSize(280,400);p_1.setBackground(Color.LIGHT_GRAY);p_2.setBackground(Color.LIGHT_GRAY);p_3.setBackground(Color.LIGHT_GRAY);jframe_1.add(p_1);jframe_1.add(p_2);jframe_1.add(p_3);
// 设置按钮和文本框text_1.setBounds(0,0,180,30);jbutton_1.setBounds(220,0,60,30);p_3.add(text_1);p_3.add(jbutton_1);
// 定义服务器开启或关闭按钮JButton jbutton_2= new JButton("连接服务器");JButton jbutton_3= new JButton("查看在线人数");jbutton_2.setBounds(0,0,100,40);jbutton_3.setBounds(155,0,110,40);
// 设置文本区text_area_1.setBounds(0,0,280,280);text_area_2.setBounds(0,50,280,280);
// 设置文本区不可编辑text_area_1.setEditable(false);text_area_2.setEditable(false);
// 定义字体(宋体,加粗)Font font_1=new Font("宋体",Font.BOLD,16);//将text_area_1作为可滚动面板sp的显示区域JScrollPane sp_1=new JScrollPane(text_area_1);JScrollPane sp_2=new JScrollPane(text_area_2);sp_1.setLocation(0,0);sp_2.setLocation(0,50);sp_1.setSize(280,280);sp_2.setSize(280,280);
// 设置文本区字体text_area_1.setFont(font_1);text_area_2.setFont(font_1);p_1.add(sp_1);p_2.add(sp_2);
// 将服务器开启和查看在线人数按钮添加到p_2p_2.add(jbutton_2);p_2.add(jbutton_3);jframe_1.setVisible(true);// 注册 发送按钮 监听EventListener e_1 = new EventListener(text_area_1,text_1);jbutton_1.addActionListener(e_1);
// 注册连接服务器按钮的监听EventListener_2 e_2=new EventListener_2(jbutton_2);jbutton_2.addActionListener(e_2);}}