java局域网聊天程序,java局域网聊天系统

  java局域网聊天程序,java局域网聊天系统

  本文实例为大家分享了爪哇实现局域网聊天室功能的具体代码,供大家参考,具体内容如下

  计算机网络服务器服务端

  导入Java。io。io异常;导入Java。io。printstream导入Java。网。服务器套接字;导入Java。网。插座;/*** 服务端*/public class Server { private static final int Server _ PORT=8080;//使用疯狂地图对象来保存每个客户名字和对应输出流之间的对应关系public static CrazyitMapString,PrintStream clients=new CrazyitMap();public void init(){ try(//建立监听的服务器套接字服务器套接字ss=新服务器套接字(SERVER _ PORT)){//采用死循环来不断地接收来自客户端的请求while(true){ Socket Socket=ss。接受();新的服务器线程(套接字)。start();} } //如果抛出异常catch(io异常ex){ system。出去。println(服务器启动失败,是否端口服务器端口已被占用);} }公共静态void main(String[]args){ Server Server=new Server();服务器。init();} }服务器线程服务端线程

  导入Java。io。缓冲阅读器;导入Java。io。io异常;导入Java。io。inputstreamreader导入Java。io。printstream导入Java。网。插座;/*** 服务端线程*/公共类ServerThread扩展线程{私有套接字Socket buffered reader br=nullPrintStream PS=null//定义一个构造器,用于接收一个窝来创建线程线程公共服务器线程(套接字套接字){ this . socket=socket } public void run(){ try {//获取该窝对应的输入流br=新缓冲读取器(新输入流读取器(套接字。getinputstream()));//获取该窝对应的输出流PS=新打印流(套接字。获取输出流());string line=null while((line=br . readline())!=null) { //如果读到的行以疯狂协议。用户_回合开始,并以其结束//则可以确定读到的是用户登录的用户名如果(行。以(CrazyitProtocol)开头.USER _ ROUND)行。以(CrazyitProtocol)结尾.USER_ROUND)) { //得到真实消息string userName=getRealMsg(line);//如果用户名重复如果(服务器。客户。地图。包含密钥(用户名)){ system。出去。println(重复);ps.println(CrazyitProtocol .NAME _ REP);}否则{

  System.out.println(userName+"上线");                        ps.println(CrazyitProtocol.LOGIN_SUCCESS);                        Server.clients.put(userName, ps);                    }                }                //如果读到的行以CrazyitProtocol.PRIVATE_ROUND开始,                //则可以确定是私聊信息,私聊信息只向特定的输入流发送                else if (line.startsWith(CrazyitProtocol.PRIVATE_ROUND) && line.endsWith(CrazyitProtocol.PRIVATE_ROUND)) {                    //得到真实的消息                    String userAndMsg = getRealMsg(line);                    //以SPLIT_SIGN分割字符串,前半是私聊用户,后半是聊天信息                    String user = userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[0];                    String msg = userAndMsg.split(CrazyitProtocol.SPLIT_SIGN)[1];                    //获取私聊用户对应的输出流,并发送私聊信息                    Server.clients.map.get(user).println(Server.clients.getKeyByValue(ps) + "悄悄对你说:" + msg);                }                //公聊要向每一个Socket发送                else {                    //得到真实消息                    String msg = getRealMsg(line);                    //遍历clients中的每个输出流                    for (PrintStream clientPs : Server.clients.valueSet()) {                        clientPs.println(Server.clients.getKeyByValue(ps) + "说:" + msg);                    }                }            }        }        //捕获到异常后,表明Socket对应的客户端已经出现了问题        //所以程序将其对应的输出流从Map中删除        catch (IOException e) {            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 (IOException ex) {                ex.printStackTrace();            }        }    }     //将读到的内容去掉前后协议字符,恢复成真实数据    private String getRealMsg(String line) {        return line.substring(CrazyitProtocol.PROTOCOL_LEN,line.length()-CrazyitProtocol.PROTOCOL_LEN);    }}Client 客户端

  

import javax.swing.*;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.Socket;import java.net.UnknownHostException; /** * 客户端 */public class Client {     private static final int SERVER_PORT=8080;    private Socket socket;    private PrintStream ps;    private BufferedReader brServer;    private BufferedReader keyIn;     public void init(){        try        {            //初始化代表键盘的输入流            keyIn=new BufferedReader(new InputStreamReader(System.in));            //连接到服务器端            socket=new Socket("127.0.0.1",SERVER_PORT);            //获取该Socket对应的输入流和输出流            ps=new PrintStream(socket.getOutputStream());            brServer=new BufferedReader(new InputStreamReader(socket.getInputStream()));            String tip=" ";            //采用不断循环地弹出对话框要求输入用户名            while(true){                String userName= JOptionPane.showInputDialog(tip+"输入用户名");                //用户输入的用户名前后增加协议字符串后发送                ps.println(CrazyitProtocol.USER_ROUND+userName+CrazyitProtocol.USER_ROUND);                //读取服务器端的响应                String result=brServer.readLine();                //如果用户名重复,则开始下一次循环                if (result.equals(CrazyitProtocol.NAME_REP)){                    tip="用户名重复,请重试";                    continue;                }                //服务器端登录成功                if (result.equals(CrazyitProtocol.LOGIN_SUCCESS)){                    break;                }            }        }        //捕获到异常,关闭网络资源,并退出该程序        catch (UnknownHostException ex){            System.out.println("找不到远程服务器,请确定服务器已经启动");            closeRs();            System.exit(1);        }        catch(IOException ex){            System.out.println("网络异常,请重新登录");            closeRs();            System.exit(1);        }        //以该Socket对应的输入流启动ClientThread线程        new ClientThread(brServer).start();    }    //定义一个读取键盘输出,并以网络发送的方法    private void readAndSend(){        try        {            //不断读取键盘输入            String line=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 (IOException ex){            System.out.println("网络通信异常!请重新登录");            closeRs();            System.exit(1);        }    }    //关闭Socket,输入流,输出流的方法    private void closeRs(){        try        {            if (keyIn!=null){                ps.close();            }            if (brServer!=null){                ps.close();            }            if (ps!=null){                ps.close();            }            if (socket!=null){                keyIn.close();            }        }        catch (IOException ex){            ex.printStackTrace();        }    }     public static void main(String[] args){        Client client=new Client();        client.init();        client.readAndSend();    }}

ClientThread 客户端线程

 

  

import java.io.BufferedReader;import java.io.IOException; /** * 客户端线程 */public class ClientThread extends Thread {     //该客户端线程负责处理输入流    BufferedReader br=null;    //使用一个网络输入流来创建客户端线程    public ClientThread(BufferedReader br){        this.br=br;    }    public void run(){        try        {            String line=null;            //不断地从输入流中读取数据,并将这些数据打印输出            while((line=br.readLine())!=null){                System.out.println(line);            }        }        catch (IOException ex){            ex.printStackTrace();        }        finally {            try {                if (br!=null){                    br.close();                }            }            catch (IOException ex){                ex.printStackTrace();            }        }    }}

CrazyitMap 容器

 

  

import java.util.*; /** * map容器 * * @param <k> * @param <v> */public class CrazyitMap<k,v> {     //创建一个线程安全的HashMap    public Map<k,v> map= Collections.synchronizedMap(new HashMap<k,v>());    //根据value来删除指定项    public synchronized void removeByValue(Object value){        for (Object key:map.keySet()){            if (map.get(key)==value){                map.remove(key);                break;            }        }    }    //获取所有value组成的Set集合    public synchronized Set<v> valueSet(){        Set<v> result=new HashSet<v>();        //将map中的所有value添加到result集合中        map.forEach((key,value)->result.add(value));        return result;    }    //根据value查找key    public synchronized k getKeyByValue(v value){        //遍历所有key组成的集合        for (k key:map.keySet()){            //如果指定key对应的value与被搜索的value相同,则返回对应的key            if(map.get(key)==valuemap.get(key).equals(value)){                return key;            }        }        return null;    }    //实现put()方法,该方法不允许value重复    public synchronized v put(k key,v value){        //遍历所有value组成的集合        for (v val:valueSet()){            //如果某个value与试图放入集合的value相同            //则抛出一个RuntimeException异常            if (val.equals(value)&&val.hashCode()==value.hashCode()){                throw new RuntimeException("MyMap实例不允许有重复的value");            }        }        return map.put(key,value);    }}

CrazyitProtocol 接口

 

  

/** * 自定义接口 */public interface CrazyitProtocol {     //定义协议字符串的长度    int PROTOCOL_LEN=2;    //下面是一些协议字符串,服务器端和客户端交换的信息都应该在前后添加这种特殊字符串    String MSG_ROUND="ηθ";    String USER_ROUND="∏∑";    String LOGIN_SUCCESS="1";    String NAME_REP="-1";    String PRIVATE_ROUND="★【";    String SPLIT_SIGN="卐";}

测试

1、启动服务端

 

  

 

  2、启动客户端 (上线)

  

 

  

 

  3 、群发

  

 

  4、私聊 (//名字:)

  

 

  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持盛行IT。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: