Java简易版:UDP协议实现群聊

 要先 运行服务端,在运行客户端,否则会报错。

服务端:

package 二十一章;



import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class T{
   public static ServerSocket server_socket;
   public static ArrayList<Socket> socketList=new ArrayList<Socket>();  
   public static void main(String []args){
       try{
           server_socket = new ServerSocket(5000);
           while(true){
               Socket socket = server_socket.accept();
               socketList.add(socket); //把sock对象加入sock集合
               ServerBO_Thread st=new ServerBO_Thread(socket,socketList); //初始化多线程
               st.start();//启动多线程
           }
       }catch(Exception ex){
           ex.printStackTrace();
       }finally{
           try{
               if(server_socket!=null){
                   server_socket.close();
               }
           }catch(Exception ex){
               ex.printStackTrace();
           }
       }
   }
   public void encryptWrite(String src,DataOutputStream output)throws IOException{
       //将一个字符串转化为字符数组
       //System.out.println(src);
       char[] char_arr = src.toCharArray();
       //加密操作
       for(int i = 0;i<char_arr.length;i++){
           output.writeChar(char_arr[i]+13);
       }
       //用作结束标志符
       output.writeChar(2333);
       output.flush();
   }
   //读取并解密
   public String readDecrypt(DataInputStream input)throws IOException{
       String rtn="";
       while(true){
           int char_src =input.readChar();
           if(char_src!=2333){
               rtn=rtn+(char)(char_src-13);
           }else{
               break;
           }
       }
       return rtn;
   }
}
class ServerBO_Thread extends Thread{
   Socket client = null;
   ArrayList<Socket> clients;
   ServerBO_Thread(Socket s,ArrayList<Socket> ss){//初始化
       client=s;
       clients=ss; 
   }
   public void run(){
       DataInputStream input = null;
       DataOutputStream output =null;
       try{
           input = new DataInputStream(client.getInputStream());
           T bo = new T();
           String receive=null;
           String send=null;
           while(true){//监视当前客户端有没有发来消息
               if(!client.isClosed()){
                   receive=bo.readDecrypt(input);
                   clients.trimToSize();
                   String[] param = receive.split("&");
                   if(")start".equals(param[1])){    //分析客户端发来的内容
                       send = param[0]+"进入聊天室";
                   }else{
                       send = param[0]+"说:    "+param[1];
                   }
                   if(!("3333".equals(param[1]))){//3333为退出聊天室信号
                       for(Socket socket:clients){ //遍历socke集合 
                           //把读取到的消息发送给各个客户端  
                           if(!socket.isClosed()){
                               output = new DataOutputStream(socket.getOutputStream());
                               bo.encryptWrite(send,output);
                           }
                       }  
                   }else{//如果有客户端退出
                       for(Socket socket:clients){ //遍历socke集合 
                               if(socket!=client){//告诉其他人此人退出聊天室
                                   if(!(socket.isClosed())){
                                       output = new DataOutputStream(socket.getOutputStream());
                                       bo.encryptWrite(param[0]+"已退出聊天室",output);
                                   }
                               }
                           }
                       output = new DataOutputStream(client.getOutputStream());
                       bo.encryptWrite("3333",output);//返回信号给要退出的客户端,然后关闭线程
                       client.close();
                       input.close();
                       output.close();
                   }
               }else{
                   break;
               }
           }
       }catch(Exception ex){
           ex.printStackTrace();
       }
   }
}

客户端: 

package 二十一章;


import java.io.IOException;
import java.util.Scanner;
import java.net.*;
import java.io.*;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.DataOutputStream;
public class People{
//服务端ip
   public  String ip = "127.0.0.1";
   //服务端端口
   public  int port = 5000;
   public  DataOutputStream output = null;
   public  Socket socket = null;
   public  DataInputStream input = null;
   public  Scanner sc =new Scanner (System.in);
   public  String send ;
   public  String receive;
   public  String name;
   public String sd = null;
   public static void main(String[]aa){
       People po = new People();
       po.start();
   }
   public void start(){
       try{
           System.out.println("*******欢迎使用匿名聊天室!**********");
           System.out.println("请输入你将要使用的昵称:");
           name=sc.nextLine();//获取昵称
           socket = new Socket(ip,port);
           output=new DataOutputStream(socket.getOutputStream());
           input = new DataInputStream(socket.getInputStream());
           send = name+"&)start";//把昵称发送到server 告诉所有人有新成员加入聊天室
           System.out.println("(如果要退出聊天室请输入“3333”!)");
           System.out.println("*******成功进入匿名聊天室!**********");
           System.out.println("");
           encryptWrite(send,output);
           Out out=new Out(output,name,input,socket);
           out.start();//启动发送聊天内容的多线程
           while(true){    
               String receive = readDecrypt(input);
               if("3333".equals(receive)){//如果收到“3333”则退出聊天室
                   System.out.println("*******成功退出匿名聊天室!**********");
                   input.close();
                   output.close();
                   socket.close();
                   System.exit(0);
               }
               System.out.println(receive);
           }
       }catch(Exception ex){
               ex.printStackTrace();
       }finally{
           try{
               if(socket!=null) socket.close();
               input.close();
               output.close();
           }catch(Exception ex){
               ex.printStackTrace();
           }
       }    
   }
   public void encryptWrite(String src,DataOutputStream output)throws IOException{
       //将一个字符串转化为字符数组
       char[] char_arr = src.toCharArray();
       //加密操作
       for(int i = 0;i<char_arr.length;i++){
           output.writeChar(char_arr[i]+13);
       }
       //用作结束标志符
       output.writeChar(2333);
       output.flush();
   }
   //读取并解密
   public String readDecrypt(DataInputStream input)throws IOException{
       String rtn="";
       while(true){
           int char_src =input.readChar();
           if(char_src!=2333){
               rtn=rtn+(char)(char_src-13);
           }else{
               break;
           }
       }
       return rtn;
   }
}
class Out extends Thread {
   public DataOutputStream output;
   public DataInputStream input;
   public static String name;
   public Socket socket;
   public  Scanner sc =new Scanner (System.in);
   Out(DataOutputStream ot,String n,DataInputStream it,Socket socket){
       output=ot;
       input=it;
       name=n;
   }
   public void run(){
       People po = new People();
       try{
           while(true){
               String send=sc.nextLine();//获取用户输入
               String send2=name+"&"+send;//把聊天内容打包成约定形式
               po.encryptWrite(send2,output);
           }
       }catch(Exception ex){
           ex.printStackTrace();
       }finally{
           System.out.println("sfef");
       }
   }
}

运行结果:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/225314.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EasyX图形化学习

1.EasyX是什么&#xff1f; 是基于Windows的图形编程&#xff0c;给用户提供函数接口&#xff0c;最终函数调用会由Windows的API实现。 注&#xff1a;EasyX只适配 c 。 2.头文件&#xff1a; <easyx.h>---只包含最新的函数 <graphics.h>---包含<easyx.h&g…

Vue3整合Element Plus过程

Vue 是一种流行的JavaScript框架&#xff0c;用于构建交互式和现代化的Web应用程序。Vue 3是Vue框架的最新版本&#xff0c;带来了新特性和改进。而Element Plus是一个基于Vue框架的UI组件库&#xff0c;它提供了丰富的UI组件和样式&#xff0c;能够帮助我们快速构建出漂亮且功…

Towards High-Quality and Efficient Video Super-Resolution via

code:coulsonlee/STDO-CVPR2023: [CVPR2023] Towards High-Quality and Efficient Video Super-Resolution via Spatial-Temporal Data Overfitting (github.com) 随着深度卷积神经网络&#xff08;DNN&#xff09;在计算机视觉的各个领域得到广泛应用&#xff0c;利用DNN的过…

ShellShock(CVE-2014-6271)

漏洞简介 GNU Bash 4.3及之前版本在评估某些构造的环境变量时存在安全漏洞&#xff0c;向环境变量值内的函数定义后添加多余的字符串会触发此漏洞&#xff0c;攻击者可利用此漏洞改变或绕过环境限制&#xff0c;以执行Shell命令。某些服务和应用允许未经身份验证的远程攻击者提…

电商早报 | 12月7日| 阿里巴巴分红179亿,破历史记录

阿里巴巴将派发25亿美元年度股息 12月6日消息&#xff0c;阿里巴巴发布公告&#xff0c;将向截至2023年12月21日香港时间及纽约时间收市时登记在册的普通股持有人和美国存托股持有人&#xff0c;就2023财年首次派发年度股息&#xff0c;金额分别为每股普通股0.125美元或每股美…

【EI会议征稿中】2024年第四届数字信号与计算机通信国际学术会议(DSCC 2024)

2024年第四届数字信号与计算机通信国际学术会议&#xff08;DSCC 2024&#xff09; 2024 4th International Conference on Digital Signal and Computer Communications 第四届数字信号与计算机通信国际会议(DSCC 2024)将于2024年4月12日至14日在中国-香港举行。DSCC 2024旨…

MATLAB机器人对偏导数、雅克比矩阵、行列式的分析与实践

偏导数、雅克比矩阵、行列式都是非常重要的知识点&#xff0c;为了让大家更容易看懂&#xff0c;尽量使用画图来演示。 1、偏导数Partial derivative 对于导数我们已经很清楚了&#xff0c;某点求导就是某点的斜率&#xff0c;也就是这点的变化率。那么偏导数是什么&#xff…

抖去推微信小程序版:短视频矩阵系统视频剪辑+无人直播

短视频矩阵获客工具的出现&#xff0c;给矩阵号的管理及运营带来了极大的便利&#xff0c;大家可以批量生成作品&#xff0c;并且可以实现自动发布&#xff0c;极大的节省了人力物力。 然而&#xff0c;对于中小商家来说虽然很想购买一套这样的系统&#xff0c;但考虑到费用较高…

外贸平台自建站的教程?做海洋建站的好处?

外贸平台自建站怎么做&#xff1f;搭建网站的具体流程有哪些&#xff1f; 作为外贸从业者&#xff0c;借助互联网平台自建站点已经成为推广业务、拓展市场的一种重要手段。海洋建站将为您提供一份详尽的外贸平台自建站的教程&#xff0c;助您在网络空间中展现您的企业魅力。 …

备战2024年1月AMC8美国数学竞赛新方式:刷在线真题集(附资源)

今天是2023年12月7日&#xff0c;距离暂定于2024年1月19日举办的AMC8美国数学竞赛的举办日期还有42天&#xff0c;有志于尽早出国留学&#xff0c;或者小升初冲击名校的孩子们相信已经在如火如荼地利用课余时间上辅导班或者自学。 为了帮助大家提高备考2024年1月份AMC8竞赛的效…

QxOrm 如何自定义主键?

默认情况下QxOrm的主键是long类型自增的&#xff0c;但是有时候我们不想使用这个主键&#xff0c;想使用比如string类型的主键。 可以使用QX_REGISTER_PRIMARY_KEY宏定义另一种类型&#xff08;例如&#xff0c;QString 类型&#xff09;的唯一 id&#xff08;主键&#xff09…

第 7 部分 — 增强 LLM 安全性的策略:数学和伦理框架

一、说明 增强大型语言模型 (LLM) 安全性的追求是技术创新、道德考虑和实际应用的复杂相互作用。这项努力需要一种深入而富有洞察力的方法&#xff0c;将先进的数学模型与道德原则和谐地融合在一起&#xff0c;以确保LLM的发展不仅在技术上稳健&#xff0c;而且在道德上合理且对…

实现简易的一对一用户聊天

服务端 package 一对一用户;import java.awt.BorderLayout; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector…

Linux 存储管理

内容概述 磁盘结构分区类型管理分区管理文件系统挂载设备管理swap空间&#xff08;用来缓解内存空间不足情况&#xff09;RAID 管理LVM管理LVM快照 1 磁盘结构 1.1 设备文件 块设备文件&#xff1a;数据的访问单位是块Block&#xff0c;一个块的IO 字符设备文件&#xff1a…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《计及需求响应与火–储深度调峰定价策略的电力系统双层优化调度》

这个标题似乎涉及到电力系统的双层优化调度问题&#xff0c;并考虑了两个关键方面&#xff1a;需求响应和火–储深度调峰定价策略。 电力系统双层优化调度&#xff1a;这指的是在电力系统中进行优化调度的过程。双层优化可能意味着系统具有两个层次的决策过程&#xff0c;通常是…

python实战—核心基础1(高考倒计时)lv1

目录 一、核心代码解释 二、代码 三、运行截图 一、核心代码解释 1、datetime模块 Python有一个名为datetime的模块&#xff0c;用于处理日期和时间。 datetime模块中定义的一个类是datetime类。 可以使用now()方法创建一个包含当前本地日期和时间的datetime对象。 impo…

外汇天眼:市场95%的输家都犯了这个错误,你也中招了吗?

下单的是人&#xff0c;由于人的不完美与无经验&#xff0c;因之会产生很多障碍&#xff0c;没有累积足够之经验&#xff0c;获得周全之要领前&#xff0c;通常会犯了主要是人就会不自觉犯下主观与判断上的差错&#xff0c;这也就是&#xff0c;95%为输家的原因。 由于投资人在…

安装和初始化 VyOS 虚拟机

目录 安装和初始化 VyOS虚拟机1. 安装VyOS系统&#xff08;1&#xff09;进入系统安装界面 2. 登录VyOS系统&#xff08;1&#xff09;安装 Image 镜像&#xff08;2&#xff09;进入初始话设置文字描述重启系统 3. 配置路由3.1 设置静态IP地址3.2 SSH端口设置3.3 删除网卡IP地…

uniapp实战 —— 自定义顶部导航栏

效果预览 下图中的红框区域 范例代码 src\pages.json 配置隐藏默认顶部导航栏 "navigationStyle": "custom", // 隐藏默认顶部导航src\pages\index\components\CustomNavbar.vue 封装自定义顶部导航栏的组件&#xff08;要点在于&#xff1a;获取屏幕边界…

springboot 自定义响应

自定义响应类是指在开发中&#xff0c;根据业务需求自定义的用于封装接口响应数据的类。通常情况下&#xff0c;一个自定义响应类包含了接口返回的相关信息&#xff0c;如状态码、消息、数据等。 自定义响应类的设计灵活多样&#xff0c;可以根据具体的业务需求进行定义。一般…