注册 登录
编程论坛 JAVA论坛

连接一个客户端时很正常,在连接几个时,输入几句话之后,就在那阻塞了,有没有大佬知道该如何解决

Gband 发布于 2018-09-08 19:54, 1753 次点击
程序代码:
public class ServerPort {
   
    static HashMap<String , String> clientMsg = new HashMap<>();//储存用户账号与密码
    static HashMap<String , Socket> clientPort = new HashMap<>();//储存用户账号与端口
    static ServerSocket server = null;
    public static void main(String[] args) {
        System.out.println("----服务端-----");
        try {
            server = new ServerSocket(8888);
            while(true)
            {
                Socket socket = server.accept();
                System.out.println("已连接一个客户端");
                //每有一个客户端接入,就创建一个子线程处理
                new SubThread(socket).start();
            }
            
        
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
   
    //子线程
    static class SubThread extends Thread
    {
        Socket s = null;
        static DataInputStream dis = null;//输入流
        static DataOutputStream dos = null;//输出流
        String clientName = "";//用户账号
        String clientPas = "";//用户密码
        public SubThread(Socket s)
        {
            this.s = s;
        }
        public void run()
        {
            String msg = "";
            boolean endFlag = false;//结束标志
            
//分析数据
            try {
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());
                while(!endFlag)
                {
                    System.out.println("出错了");
                    msg = dis.readUTF();  //Bug
                    
                    
//请求登录数据
                    if(msg != null && msg.startsWith("flag"))
                    {
                        String[] datas = msg.split("&");
                        clientName = datas[0].split("=")[1];
                        clientPas = datas[1].split("=")[1];
                        if(clientMsg.isEmpty())
                        {
                            clientMsg.put(clientName, clientPas);
                            clientPort.put(clientName, s);
                            dos.writeUTF("flag");
                            dos.flush();
                            SubThread.send(clientName + "上线了", dos);
                        }
                        else {
                            for(Entry<String, String> entry : clientMsg.entrySet())
                            {
                                //用户名与密码正确则允许登录,并发送登录许可标志
                                if((entry.getKey().equals(clientName)) && (entry.getValue().equals(clientPas)))
                                {
                                        dos.writeUTF("flag");
                                        dos.flush();
                                        SubThread.send(clientName + "上线了", dos);
                                }
                                //信息错误
                                else if((entry.getKey().equals(clientName)) && (!entry.getValue().equals(clientPas)))
                                {
                                    //给客户端发送错误反馈
                                    dos.writeUTF("failture");
                                    dos.flush();
                                    //用户名或密码错误就释放资源并关闭
                                    release();
                                    return;
                                }
                                //还无此用户信息的情况时
                                else {
                                    clientMsg.put(clientName, clientPas);
                                    clientPort.put(clientName, s);
                                    dos.writeUTF("flag");
                                    dos.flush();
                                    SubThread.send(clientName + "上线了", dos);
                                }
                            }
                        }
                        
                    }
                    //私聊信息,私聊格式指定:@name:msg
                    else if(msg.startsWith("@"))
                    {
                        String anoName = msg.split(":")[0].split("=")[1];
                        String message = msg.split(":")[1];               
                        Socket anoSocket = clientPort.get(anoName);
                        dos = new DataOutputStream(anoSocket.getOutputStream());
                        dos.writeUTF(clientName + "悄悄对你说: " + message);
                        dos.flush();
                    }
                    //正常的普通消息
                    else {
                        if(!msg.equals("Bye"))
                        {
                            //String name = nameBySocket(s);
                            SubThread.send(clientName + ": " + msg, dos);
                            System.out.println(clientName + ": " + msg);
                        }
                        else {
                            dos.writeUTF("end");
                            dos.flush();
                            String clientName = nameBySocket(s);
                            SubThread.send(clientName + "已下线", dos);
                            release();//释放资源
                            endFlag = true;
                        }
                           
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
        }   
    }
        //发送消息给多个客户端
        static void send(String msg, DataOutputStream dos)
        {
            try {
                Collection<Socket> socketList = clientPort.values();
                for(Socket s1 : socketList)
                {
                    dos = new DataOutputStream(s1.getOutputStream());
                    dos.writeUTF(msg);
                    dos.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }        
        }
        

        //释放子线程资源
        private void release()
        {
            try {
                if(null != dos)
                    dos.close();
                if(null != dis)
                    dis.close();
                 s.close();
            } catch (Exception e) {
                e.printStackTrace();
            }   
       }
        
    }

}
1 回复
#2
林月儿2018-09-23 12:41
服务器端在向客户端发消息时,可以另起一个任务线程试试。
1