标题:连接一个客户端时很正常,在连接几个时,输入几句话之后,就在那阻塞了,有 ...
只看楼主
Gband
Rank: 1
等 级:新手上路
帖 子:41
专家分:7
注 册:2017-10-13
结帖率:88.89%
 问题点数:0 回复次数:1 
连接一个客户端时很正常,在连接几个时,输入几句话之后,就在那阻塞了,有没有大佬知道该如何解决
程序代码:
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();
            }    
       }
        
    }

}
搜索更多相关主题的帖子: static String new Socket dos 
2018-09-08 19:54
林月儿
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:湖南
等 级:版主
威 望:138
帖 子:2276
专家分:10647
注 册:2015-3-19
得分:0 
服务器端在向客户端发消息时,可以另起一个任务线程试试。

剑栈风樯各苦辛,别时冰雪到时春
2018-09-23 12:41



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-489704-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.348668 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved