Java:JavaSocket编程开发多人聊天室「建议收藏」

Java:JavaSocket编程开发多人聊天室「建议收藏」Java|JavaSocket编程开发多人聊天室实现内容运行结果部分代码完整代码实现内容用Java图形用户界面编写聊天室服务器端和客户端,支持多个客户端连接到一个服务器。每个客户端能够输入账号。可以实现群聊(聊天记录显示在所有客户端界面)。完成好友列表在各个客户端上显示。可以实现私人聊天,用户可以选择某个其他用户,单独发送信息。服务器能够群发系统消息,能够强行让某些用户下线。客户端的上线下线要求能够在其他客户端上面实时刷新。运行结果部分代码importjava.awt

大家好,又见面了,我是你们的朋友全栈君。

Java:JavaSocket编程开发多人聊天室

实现内容

  1. 用Java图形用户界面编写聊天室服务器端和客户端, 支持多个客户端连接到一个服务器。每个客户端能够输入账号。
  2. 可以实现群聊(聊天记录显示在所有客户端界面)。
  3. 完成好友列表在各个客户端上显示。
  4. 可以实现私人聊天,用户可以选择某个其他用户,单独发送信息。
  5. 服务器能够群发系统消息,能够强行让某些用户下线。
  6. 客户端的上线下线要求能够在其他客户端上面实时刷新。

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

部分代码

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
import javax.swing.*;

public class ClientChat extends JFrame { 
   
	private static final long serialVersionUID = 1L;
	
	
	private Socket socket ;                  //负责和服务器通信
	
	private JTextArea contentArea;           //群聊消息显示框
    private JTextArea sendArea;              //消息编辑区域
    private JTextArea friendsList;           //好友列表
    private String name;                     //用户名
    private JComboBox cmb;                   //发送对象下拉框
    
    public ClientChat(Socket socket,String name)  { 
   
    	
        this.socket = socket ;
        this.name  = name ;
        
        this.init();        //初始化聊天客户端
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setVisible(true);
       
        //接下来启动单独线程,从服务器中读取数据
        ClientThread thread  = new ClientThread(socket,contentArea,cmb) ;
        thread.start();
        
    }
   
    public void init( )  { 
   
        this.setTitle("我的聊天室");
        this.setSize(500,500);
        int x = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth() ;
        int y = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight() ;
       
        this.setLocation( (x-this.getWidth() )/2, ( y-this.getHeight() )/2 );
        this.setResizable(false);
       
        
        contentArea = new JTextArea();
        contentArea.setLineWrap(true);  //换行方法
        JScrollPane logPanel = new JScrollPane(contentArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        contentArea.append("----------------------------消息记录--------------------------------------\n");
        
        sendArea = new JTextArea();
        sendArea.setLineWrap(true);    //控制每行显示长度最大不超过界面长度
        JScrollPane sendPanel = new JScrollPane(sendArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        
        friendsList = new JTextArea();
        friendsList.setLineWrap(true);
        JScrollPane friendPanel2 = new JScrollPane(friendsList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        friendsList.append("------------好友列表-------------\n");
        
        JSplitPane splitpane1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,logPanel,sendPanel) ;
        splitpane1.setDividerLocation(290);
        JSplitPane splitpane2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,splitpane1,friendPanel2) ;
        splitpane2.setDividerLocation(320);
        this.add(splitpane2,BorderLayout.CENTER);
       
        //按钮面板
        JPanel bPanel  = new JPanel() ;
        bPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)) ;
        this.add(bPanel,BorderLayout.SOUTH) ;
        
        JLabel toNamelabel=new JLabel("发送对象:");
        cmb=new JComboBox(); 
        cmb.addItem("所有人");
        bPanel.add(toNamelabel);
        bPanel.add(cmb);
       
        JLabel namelabel = new JLabel("用户名: "+this.name+" ") ;
        bPanel.add(namelabel) ;
       
        JButton closeButton = new JButton("退 出") ;
        closeButton.addActionListener( new ActionListener() { 
     //退出按钮监听
            public void actionPerformed(ActionEvent e)  { 
   
            	
            	String sendStr = name + "!!!!" ;
                PrintWriter out = null ;
                try  { 
   
                    out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream() ) ) ;
                    out.println(sendStr) ;
                    out.flush();
                }catch(Exception ex)  { 
   
                    ex.printStackTrace();
                }
                
            	exit();
            }
        });
        bPanel.add(closeButton) ;
       
        JButton sendButton = new JButton("发 送") ;
        sendButton.addActionListener(new ActionListener() { 
     //发送按钮监听
            public void actionPerformed(ActionEvent e) { 
   
                String str = sendArea.getText();  //获取发送的消息
                SimpleDateFormat formater = new SimpleDateFormat("HH:mm:ss") ;  //获取当前时间
                String time  = formater.format(new Date() ) ;
                String toName = (String) cmb.getSelectedItem();  //获取发送对象
                
                //发送给服务器的消息格式为 时间 本客户端用户名 对 发送对象 说: 消息 <本客户端用户名>(发送对象)
                String sendStr = time + " " + name + " 对 " + toName +" 说: "+ str + "<" + name +">" + "(" + toName + ")";
                PrintWriter out = null ;
                try  { 
   
                    out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream() ) ) ;  //发送给服务器
                    out.println(sendStr) ;
                    out.flush();
                }catch(Exception ex)  { 
   
                    ex.printStackTrace();
                }
                sendArea.setText("");
            }
        });
        bPanel.add(sendButton) ;   
            
    }
    
	public void exit() { 
      //退出
		this.dispose();
		System.exit(0);
	}
	

//客户端与服务器端通信的线程类
class ClientThread extends Thread  { 
   
    private Socket socket ;
    private JTextArea contentArea ;
    private JComboBox cmb;
   
    public ClientThread(Socket socket, JTextArea  conteArea , JComboBox cmb) { 
   
        this.socket = socket ;
        this.contentArea = conteArea ;
        this.cmb = cmb;
    }
   
    public void run() { 
   
        BufferedReader br = null ;
        try  { 
   
            br = new BufferedReader(new InputStreamReader(socket.getInputStream())) ;
            String str = null ;
            while( (str = br.readLine()) != null) { 
   
            	if(str.endsWith("上线了 ]")) { 
     //新用户上线,加入列表中
            		if(!str.substring(3, str.length()-5).equals(name)) { 
   
            			friendsList.append(str.substring(3, str.length()-5));
            			friendsList.append("\n");
            			cmb.addItem(str.substring(3, str.length()-5));
            		}
            		contentArea.append(str);
                	contentArea.append("\n");
            	}
            	else if(str.endsWith("下线了 ]")) { 
     //用户下线
            		contentArea.append(str);
                    contentArea.append("\n");
                    	
                    cmb.removeItem(str.substring(3, str.length()-5));
            	} 
            	else if(str.endsWith("被强制下线 ]")) { 
     //服务器强制下线消息
            		if(str.substring(3, str.length()-7).equals(name)) { 
   
            			exit();
            		}
            		else { 
   
            			contentArea.append(str);
                    	contentArea.append("\n");
                    	
                    	cmb.removeItem(str.substring(3, str.length()-7));
            		}
            	}
            	else if(str.endsWith("###")) { 
    //将在本客户端连接之前就已连接的客户端用户名添加到列表中
            		friendsList.append(str.substring(0, str.length()-3));
            		friendsList.append("\n");
            		cmb.addItem(str.substring(0, str.length()-3));
            	}
            	else if(str.substring(0,6).equals(" [ 通知:")) { 
     //服务器发送的系统通知
            		contentArea.append(str);
                    contentArea.append("\n");
            	}
            	else if(splitData(str,"<",">").equals(name)){ 
    //自己发送的消息
            		contentArea.append(str.substring(0, str.lastIndexOf("<")));
                	contentArea.append("\n");
            	}
            	else if(splitData(str,"(",")").equals(name)){ 
    //别人私聊给自己的消息
            		contentArea.append(str.substring(0, str.lastIndexOf("<")));
                	contentArea.append("\n");
            	}
            	else if(splitData(str,"(",")").equals("所有人")) { 
    //对所有人发送的消息
            		contentArea.append(str.substring(0, str.lastIndexOf("<")));
                	contentArea.append("\n");
            	}
            }
        }catch(Exception ex) { 
   
            ex.printStackTrace();
        }finally { 
   	
            if(br != null) { 
   
                try { 
   
                    br.close () ;
                }catch(IOException e) { 
   
                	e.printStackTrace();
                }
            }
        }
    }
    
    public String splitData(String str, String strStart, String strEnd) { 
     //获取字符串中某两个字符间的字符串
    	String tempStr;
    	tempStr = str.substring(str.indexOf(strStart) + 1, str.lastIndexOf(strEnd));
    	return tempStr;
    }
	}
}

完整代码

用JavaSocket编程开发多人聊天室(群聊、私聊等)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150004.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql fsync_用一分钟了解: fsync这个系统调用!

    mysql fsync_用一分钟了解: fsync这个系统调用!1前言不要诧异在MySQL专题中突然插入fsync系统调用,因为马上就要和大家分享MySQL的undolog、redolog、binlog了,在分享这些文章的时候会经常说fsync这个名词,所以提前来看下。2缓冲传统的UNIX实现的内核中都设置有缓冲区或者页面高速缓存,大多数磁盘IO都是通过缓冲写的。当你想将数据write进文件时,内核通常会将该数据复制到其中一个缓冲区中,如果该缓冲没被写满…

    2022年5月31日
    45
  • media type的类型汇总

    media type的类型汇总用的比较多的是screen和print:区分打印和屏幕显示(Android,iPhone都不是手持设备handheld,都是screen设备)转载于:https://www.cnblogs.com/hulaoxi/p/6140054.html

    2022年5月25日
    85
  • SIGABRT 报错时的注意事项和解决方法

     SIGABRT报错,可以理解为安卓系统为保护自身安全,清理了你的应用,这样导致的应用崩溃,通常是在读取file或者结束某个逻辑操作时,没有及时的释放资源,这样会导致报错。我接触到这个崩溃问题,是因为需要多次频繁的加载webview时导致的,在ondestroy方法里,加上webview.destroy(),此时崩溃的次数明显减少,但是偶有崩溃,查找了网上很多答案,都未能解决问题,这时突然想到…

    2022年4月16日
    96
  • ORAN专题系列-1:什么是开放无线接入网O-RAN「建议收藏」

    这篇文章将回答如下几个问题:什么是无线接入网RAN?什么是开放无线接入网ORAN?ORAN与5G的关系?ORAN提出的动机?ORAN的参与方?以及ORAN的技术目标?ORAN标准的组织架构?

    2022年4月16日
    32
  • 【时间序列预测】基于matlab CNN优化LSTM时间序列预测(单变量单输出)【含Matlab源码 1688期】「建议收藏」

    一、CNN简介二、LSTM简介1LSTM控制流程LSTM的控制流程:是在前向传播的过程中处理流经细胞的数据,不同之处在于LSTM中细胞的结构和运算有所变化。这一系列运算操作使得LSTM具有能选择保存信息或遗忘信息的功能。咋一看这些运算操作时可能有点复杂,但没关系下面将带你一步步了解这些运算操作。2核心概念LSTM的核心概念在于细胞状态以及“门”结构。细胞状态相当于信息传输的路径,让信息能在序列连中传递下去。你可以将其看作网络的“记忆”。理论上讲,细胞状态能够将序列处理过程中的相关

    2022年4月16日
    79
  • 《哈佛大学公开课:幸福课》学习笔记(3)「建议收藏」

    《哈佛大学公开课:幸福课》学习笔记(3)「建议收藏」关键词/句:Howcanwegetbeyondthat”comfortablynumb”?Howcanwegetbeyondthat”queitdesperation”?focusedonthehealthandcultivatedit,watereditandshedalighttoit,realizedit.optimism,…

    2022年7月18日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号