java写了一个聊天室的程序 但是私聊第二个人就报空指针异常 不知道为什么 求解

下面是全部的代码

 package com.sram.chat;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class CrazyitMap<K,V> {
    Map<K,V> maps = Collections.synchronizedMap(new HashMap<K,V>());

    //创建一个删除指定项 如果value值相同就删除
    public synchronized void removeByValue(V value){
        for(K key:maps.keySet()){
            if(maps.get(key)==value){
                maps.remove(key);
                break;
            }
        }
    }
    public synchronized Set<V> valueSet(){
        Set<V> result = new HashSet<V>();
        for(K key:maps.keySet()){
            result.add(maps.get(key));
        }
        return result;
    }
    //根据value查找key
    public synchronized K getKeyByValue(V value){
        for(K key:maps.keySet()){
            if(maps.get(key)==value||maps.get(key).equals(value)){
                return key;
            }
        }
        return null;
    }
    //添加vlaue 但是不能重复
    public synchronized V put(K key,V value){
        for(V val:valueSet()){
            if(val.equals(value)&&val.hashCode()==value.hashCode()){
                throw new RuntimeException("Map集合中不能重复存储value");
            }
        }
        return maps.put(key, value);
    }
}

 package com.sram.chat;

public interface Protocol {
    //定义协议字符长度
        int PROTOCOL_LEN = 2;
        //下面是协议字符不同表示
        String MEG_ROUND ="∞∞";   //发送群聊聊天信息
        String USER_ROUND="ぁぁ"; //用户名
        String LOGIN_SUCCESS="1";   //登录成功
        String NAME_REP ="-1";          //重复用户名,登录失败
        String PRIVATE_ROUND ="◎◎"; //私聊
        String SPLIT_SIGN="π";
}

 package com.sram.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JOptionPane;

public class Client {
    private static final int SERVER_PORT = 6868;
    private Socket socket;
    private PrintStream ps;
    private BufferedReader brServer;//
    private BufferedReader keyIn;//
    public void init(){
        try{
            socket  = new Socket("127.0.0.1",SERVER_PORT);
            keyIn = new BufferedReader(new InputStreamReader(System.in));
            ps = new PrintStream(socket.getOutputStream());

            brServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String tip = "";
            while(true){
                String userName = JOptionPane.showInputDialog(tip+"输入用户名");
                ps.println(Protocol.USER_ROUND+userName+Protocol.USER_ROUND);
                String result = brServer.readLine();
                if(result.equals(Protocol.NAME_REP)){
                    tip = "用户名重复,请重新";
                    continue;
                }else if(result.equals(Protocol.LOGIN_SUCCESS)){

                    break;
                }

            }
        }catch(UnknownHostException e){
            System.out.println("链接不到远程服务器,请确定服务器已经启动");
            closeAll();
            System.exit(1);
        }catch(IOException e1){
            System.out.println("网络异常!请重新登录");
            closeAll();
            System.exit(1);
        }
        new ClientThread(brServer).start();
    }
    public void readAndSend(){
        try {
            String line = null;
            while((line = keyIn.readLine())!=null){
                if(line.indexOf(":")>0&&line.startsWith("@@")){
                    line = line.substring(2);//
                    ps.println(Protocol.PRIVATE_ROUND
                            +line.split(":")[0]
                            +Protocol.SPLIT_SIGN
                            +line.split(":")[1]
                            +Protocol.PRIVATE_ROUND);
                }else{
                    ps.println(Protocol.MEG_ROUND+line+Protocol.MEG_ROUND);
                }
            }
        } catch (IOException e) {e.printStackTrace();}
    }
    public static void main(String[] args) {
        Client client = new Client();
        client.init();
        client.readAndSend();
    }
    public void closeAll(){
        try{
                if(keyIn!=null){ //判断流是否创建
                    keyIn.close();
                }
                if(brServer!=null){
                    brServer.close();
                }
                if(ps!=null){
                    ps.close();
                }
                if(socket!=null){
                    socket.close();
                }
                } catch (IOException e){
                    e.printStackTrace();
                }


    }
}

 package com.sram.chat;

import java.io.BufferedReader;
import java.io.IOException;

public class ClientThread extends Thread{
    BufferedReader br = null;//处理
    public ClientThread(BufferedReader br){
        this.br= br;
    }
    @Override
    public void run() {
        String line = null;
        try {
            while((line = br.readLine())!=null){
                System.out.println(line);   
            }
        } catch (IOException e) {e.printStackTrace();}
        finally{
            try{
            if(br!=null){
                br.close();
            }
            }catch(IOException e){e.printStackTrace();}
        }
    }

}

 package com.sram.chat;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    private static final int SERVER_PORT = 6868;
    public static CrazyitMap<String,PrintStream> clients = new CrazyitMap<>();
    public void init(){
        try{
            ServerSocket ss = new  ServerSocket(SERVER_PORT);
            while(true){
                Socket s = ss.accept();
                //启动子线程,读取
                new ServerThread(s).start();;
            }
        }catch(IOException ex){
            System.out.println("服务器启动失败,是否"+SERVER_PORT+"已被占用?");
        }
    }
    public static void main(String args[]){
        Server server = new Server();
        server.init();
    }
}




 package com.sram.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class ServerThread extends Thread{
    private Socket socket;
    BufferedReader br = null;
    PrintStream ps = null;
    ServerThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try{
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            ps = new PrintStream(socket.getOutputStream());
            String line = null;
            while((line = br.readLine())!=null){
                //ぁぁstevejobsぁぁ
                //如果读到的line字符是以 Protocol.USER_ROUND开始,并且以Protocol.USER_ROUND结束,则可以确定
                //读到的是用户登录的用户名
                //System.out.println(line);
                //System.out.println(getRealMsg(line));
                if(line.startsWith(Protocol.USER_ROUND)&&line.endsWith(Protocol.USER_ROUND)){
                    String userName = getRealMsg(line);
                    if(Server.clients.maps.containsKey(userName)){
                        System.out.println("服务器提示:用户名重复");//服务器端到客户端
                        ps.println(Protocol.NAME_REP);
                    }else{
                        System.out.println("服务器提示:成功");
                        ps.println(Protocol.LOGIN_SUCCESS);
                        Server.clients.put(userName,ps);
                    }
                }else if(line.startsWith(Protocol.PRIVATE_ROUND)&&line.endsWith(Protocol.PRIVATE_ROUND)){
                    String message = getRealMsg(line);
                    String toUser = message.split(Protocol.SPLIT_SIGN)[0];
                    String msg = message.split(Protocol.SPLIT_SIGN)[1];
                    Server.clients.maps.get(toUser).println(Server.clients.getKeyByValue(ps)+"悄悄对你说:"+msg);
                }else if(line.startsWith(Protocol.MEG_ROUND)&&line.startsWith(Protocol.MEG_ROUND)){
                    String message = getRealMsg(line);
                    for(PrintStream out:Server.clients.valueSet()){
                        out.println(Server.clients.getKeyByValue(ps)+"说:"+message);
                    }
                }
            }
        }catch(IOException e){
            Server.clients.removeByValue(ps);
            System.out.println("集合Map"+Server.clients.maps.size());
                try {
                    if(br!=null){
                    br.close();
                    }
                    if(ps!=null){
                        ps.close();
                    }
                    if(socket!=null){
                        socket.close();
                    }
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
        }
    }
    private String getRealMsg(String line){
        return line.substring(Protocol.PROTOCOL_LEN,line.length()-Protocol.PROTOCOL_LEN);

    }

}

1个回答

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问