Java怎么用局域网实现聊天室功能(java,开发技术)

时间:2024-05-07 08:10:34 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

类和接口

Java怎么用局域网实现聊天室功能

Server类(服务器端)

packageTest;importjava.io.IOException;importjava.io.PrintStream;importjava.net.ServerSocket;importjava.net.Socket;publicclassServer{privatestaticfinalintSERVER_PORT=30000;//使用CrazyitMap对象来保存每个客户名字和对应输出流之间的对应关系publicstaticCrazyitMap<String,PrintStream>clients=newCrazyitMap<>();publicvoidinit(){try(//建立监听的ServerSocketServerSocketss=newServerSocket(SERVER_PORT)){//采用死循环来不断地接收来自客户端的请求while(true){Socketsocket=ss.accept();newServerThread(socket).start();}}//如果抛出异常catch(IOExceptionex){System.out.println("服务器启动失败,是否端口"+SERVER_PORT+"已被占用");}}publicstaticvoidmain(String[]args){Serverserver=newServer();server.init();}}

ServerThread类

packageTest;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintStream;importjava.net.Socket;publicclassServerThreadextendsThread{privateSocketsocket;BufferedReaderbr=null;PrintStreamps=null;//定义一个构造器,用于接收一个Socket来创建ServerThread线程publicServerThread(Socketsocket){this.socket=socket;}publicvoidrun(){try{//获取该Socket对应的输入流br=newBufferedReader(newInputStreamReader(socket.getInputStream()));//获取该Socket对应的输出流ps=newPrintStream(socket.getOutputStream());Stringline=null;while((line=br.readLine())!=null){//如果读到的行以CrazyitProtocol.USER_ROUND开始,并以其结束//则可以确定读到的是用户登录的用户名if(line.startsWith(CrazyitProtocol.USER_ROUND)&&line.endsWith(CrazyitProtocol.USER_ROUND)){//得到真实消息StringuserName=getRealMsg(line);//如果用户名重复if(Server.clients.map.containsKey(userName)){System.out.println("重复");ps.println(CrazyitProtocol.NAME_REP);}else{System.out.println("成功");ps.println(CrazyitProtocol.LOGIN_SUCCESS);Server.clients.put(userName,ps);}}//如果读到的行以CrazyitProtocol.PRIVATE_ROUND开始,//则可以确定是私聊信息,私聊信息只向特定的输入流发送elseif(line.startsWith(CrazyitProtocol.PRIVATE_ROUND)&&line.endsWith(CrazyitProtocol.PRIVATE_ROUND)){//得到真实的消息StringuserAndMsg=getRealMsg(line);//以SPLIT_SIGN分割字符串,前半是私聊用户,后半是聊天信息Stringuser=userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[0];Stringmsg=userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[1];//获取私聊用户对应的输出流,并发送私聊信息Server.clients.map.get(user).println(Server.clients.getKeyByValue(ps)+"悄悄对你说:"+msg);}//公聊要向每一个Socket发送else{//得到真实消息Stringmsg=getRealMsg(line);//遍历clients中的每个输出流for(PrintStreamclientPs:Server.clients.valueSet()){clientPs.println(Server.clients.getKeyByValue(ps)+"说:"+msg);}}}}//捕获到异常后,表明Socket对应的客户端已经出现了问题//所以程序将其对应的输出流从Map中删除catch(IOExceptione){Server.clients.removeByValue(ps);System.out.println(Server.clients.map.size());//关闭网络,IO资源try{if(br!=null){br.close();}if(ps!=null){ps.close();}if(socket!=null){socket.close();}}catch(IOExceptionex){ex.printStackTrace();}}}//将读到的内容去掉前后协议字符,恢复成真实数据privateStringgetRealMsg(Stringline){returnline.substring(CrazyitProtocol.PROTOCOL_LEN,line.length()-CrazyitProtocol.PROTOCOL_LEN);}}

Client类

packageTest;importjavax.swing.*;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintStream;importjava.net.Socket;importjava.net.UnknownHostException;publicclassClient{privatestaticfinalintSERVER_PORT=30000;privateSocketsocket;privatePrintStreamps;privateBufferedReaderbrServer;privateBufferedReaderkeyIn;publicvoidinit(){try{//初始化代表键盘的输入流keyIn=newBufferedReader(newInputStreamReader(System.in));//连接到服务器端socket=newSocket("127.0.0.1",SERVER_PORT);//获取该Socket对应的输入流和输出流ps=newPrintStream(socket.getOutputStream());brServer=newBufferedReader(newInputStreamReader(socket.getInputStream()));Stringtip="";//采用不断循环地弹出对话框要求输入用户名while(true){StringuserName=JOptionPane.showInputDialog(tip+"输入用户名");//用户输入的用户名前后增加协议字符串后发送ps.println(CrazyitProtocol.USER_ROUND+userName+CrazyitProtocol.USER_ROUND);//读取服务器端的响应Stringresult=brServer.readLine();//如果用户名重复,则开始下一次循环if(result.equals(CrazyitProtocol.NAME_REP)){tip="用户名重复,请重试";continue;}//服务器端登录成功if(result.equals(CrazyitProtocol.LOGIN_SUCCESS)){break;}}}//捕获到异常,关闭网络资源,并退出该程序catch(UnknownHostExceptionex){System.out.println("找不到远程服务器,请确定服务器已经启动");closeRs();System.exit(1);}catch(IOExceptionex){System.out.println("网络异常,请重新登录");closeRs();System.exit(1);}//以该Socket对应的输入流启动ClientThread线程newClientThread(brServer).start();}//定义一个读取键盘输出,并以网络发送的方法privatevoidreadAndSend(){try{//不断读取键盘输入Stringline=null;while((line=keyIn.readLine())!=null){//如果发送的信号中有冒号,并以//开头,则认为想发送私聊信息if(line.indexOf(":")>0&&line.startsWith("//")){line=line.substring(2);ps.println(CrazyitProtocol.PRIVATE_ROUND+line.split(":")[0]+CrazyitProtocol.SPLIT_SIGN+line.split(":")[1]+CrazyitProtocol.PRIVATE_ROUND);}else{ps.println(CrazyitProtocol.MSG_ROUND+line+CrazyitProtocol.MSG_ROUND);}}}catch(IOExceptionex){System.out.println("网络通信异常!请重新登录");closeRs();System.exit(1);}}//关闭Socket,输入流,输出流的方法privatevoidcloseRs(){try{if(keyIn!=null){ps.close();}if(brServer!=null){ps.close();}if(ps!=null){ps.close();}if(socket!=null){keyIn.close();}}catch(IOExceptionex){ex.printStackTrace();}}publicstaticvoidmain(String[]args){Clientclient=newClient();client.init();client.readAndSend();}}

ClientThread类

packageTest;importjava.io.BufferedReader;importjava.io.IOException;publicclassClientThreadextendsThread{//该客户端线程负责处理输入流BufferedReaderbr=null;//使用一个网络输入流来创建客户端线程publicClientThread(BufferedReaderbr){this.br=br;}publicvoidrun(){try{Stringline=null;//不断地从输入流中读取数据,并将这些数据打印输出while((line=br.readLine())!=null){System.out.println(line);}}catch(IOExceptionex){ex.printStackTrace();}finally{try{if(br!=null){br.close();}}catch(IOExceptionex){ex.printStackTrace();}}}}

CrazyitMap类

packageTest;importjava.util.*;publicclassCrazyitMap<k,v>{//创建一个线程安全的HashMappublicMap<k,v>map=Collections.synchronizedMap(newHashMap<k,v>());//根据value来删除指定项publicsynchronizedvoidremoveByValue(Objectvalue){for(Objectkey:map.keySet()){if(map.get(key)==value){map.remove(key);break;}}}//获取所有value组成的Set集合publicsynchronizedSet<v>valueSet(){Set<v>result=newHashSet<v>();//将map中的所有value添加到result集合中map.forEach((key,value)->result.add(value));returnresult;}//根据value查找keypublicsynchronizedkgetKeyByValue(vvalue){//遍历所有key组成的集合for(kkey:map.keySet()){//如果指定key对应的value与被搜索的value相同,则返回对应的keyif(map.get(key)==value||map.get(key).equals(value)){returnkey;}}returnnull;}//实现put()方法,该方法不允许value重复publicsynchronizedvput(kkey,vvalue){//遍历所有value组成的集合for(vval:valueSet()){//如果某个value与试图放入集合的value相同//则抛出一个RuntimeException异常if(val.equals(value)&&val.hashCode()==value.hashCode()){thrownewRuntimeException("MyMap实例不允许有重复的value");}}returnmap.put(key,value);}}

CrazyitProtocol类

packageTest;publicinterfaceCrazyitProtocol{//定义协议字符串的长度intPROTOCOL_LEN=2;//下面是一些协议字符串,服务器端和客户端交换的信息都应该在前后添加这种特殊字符串StringMSG_ROUND="ηθ";StringUSER_ROUND="∏∑";StringLOGIN_SUCCESS="1";StringNAME_REP="-1";StringPRIVATE_ROUND="★【";StringSPLIT_SIGN="卐";}

运行结果:

打开服务器并且运行三个客户端用户名分别是xuwei,jiji和yaou

Java怎么用局域网实现聊天室功能

首先发送一句公开信息:
xuwei发送了一句话

Java怎么用局域网实现聊天室功能

jiji收到:

Java怎么用局域网实现聊天室功能

yaou收到:

Java怎么用局域网实现聊天室功能

再发送一句私聊信息给jiji
xuwei发送了一句悄悄话:

Java怎么用局域网实现聊天室功能

jiji收到:

Java怎么用局域网实现聊天室功能

yaou没有收到:

Java怎么用局域网实现聊天室功能

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Java怎么用局域网实现聊天室功能的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Python怎么远程控制Windows服务器下一篇:

9 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18