Java 在循环中逐个创建套接字数的问题

Java 在循环中逐个创建套接字数的问题,java,android,sockets,wifi,serversocket,Java,Android,Sockets,Wifi,Serversocket,我制作了一个学校应用程序,其中老师向学生发送一条字符串消息。教师持有已登录学生的哈希图。当老师在他的平板电脑中按下下一页命令时,学生应该看到下一页。这就是通常发生的情况,但有时当老师由于某种原因无法与散列图中的单个学生建立连接时,整个过程会变得非常缓慢,系统很少停止进一步响应 public static void SendToEveryStudent(String message) throws IOException, ELearningException { String c

我制作了一个学校应用程序,其中老师向学生发送一条字符串消息。教师持有已登录学生的哈希图。当老师在他的平板电脑中按下下一页命令时,学生应该看到下一页。这就是通常发生的情况,但有时当老师由于某种原因无法与散列图中的单个学生建立连接时,整个过程会变得非常缓慢,系统很少停止进一步响应

public static void SendToEveryStudent(String message) throws IOException, ELearningException 
{   
    String command;
    String host;
    int port;
    String failedStudents = "";
    int leftOverStudents = 0;
    ApplicationLog.log("Command Queue: sendToEveryStudent : " + message, InitializeTeacherJar.getInstance().isLoggingEnabled());
    int socketTimeout;

    Socket studentSocket = null;

    StudentUtility.studentCounter = 0;

    port = InitializeTeacherJar.getGlobalPort();
    socketTimeout = InitializeTeacherJar.getInstance().getTeacherStudentSocketTimeout();

    // Check if no of students are more then zero
    if (InitializeTeacherJar.getInstance().getStudentIPList().keySet().size() > 0)
    {
        StudentUtility.studentCounter = InitializeTeacherJar.getInstance().getStudentIPList().keySet().size();

        for (String key : InitializeTeacherJar.getInstance().getStudentIPList().keySet())
        {
            try 
            {   
                host = InitializeTeacherJar.getInstance().getStudentIPList().get(key).get(0);

                if (!host.equalsIgnoreCase(""))
                {   
                    if (studentSocket != null)
                    {
                        studentSocket.close();
                        studentSocket = null;
                    }

                    try
                    {   
                        studentSocket = new Socket(InetAddress.getByName(host), port);
                        studentSocket.setSoTimeout(socketTimeout);
                    }
                    catch (Exception e)
                    {
                        leftOverStudents++;
                        failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
                        ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
                        continue;
                    }

                    if (studentSocket != null)
                    {
                        if (InitializeTeacherJar.getInstance().getStudentIPList().get(key).get(1).equalsIgnoreCase("present"))
                        {
                            studentSocket.getOutputStream().write((message + "\n").getBytes());

                            ApplicationLog.log("Command Queue: Message to student :: " + message + " :: " + key, InitializeTeacherJar.getInstance().isLoggingEnabled());

                            BufferedReader in = new BufferedReader(new InputStreamReader(studentSocket.getInputStream()));

                            String line = null;

                            while ((line = in.readLine()) != null)
                            {
                                if (line.equalsIgnoreCase("ack"))
                                {
                                    //ApplicationLog.log("InitializeTeacherJar :: Student Counter is :: " + StudentUtility.studentCounter, InitializeTeacherJar.getInstance().isLoggingEnabled());
                                    ApplicationLog.log("Command Queue: Ack recvd for :: "+ key + " :: " + host, InitializeTeacherJar.getInstance().isLoggingEnabled());
                                }
                                else
                                {
                                    ApplicationLog.log("Command Queue: Did Not received ACK for :: "+ key + " :: " + host, InitializeTeacherJar.getInstance().isLoggingEnabled());
                                }
                            }
                        }
                        else 
                        {
                            studentSocket.getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + ErrorCodes.TABLET_NOT_ASSIGNED).getBytes());

                            ApplicationLog.log("StudentUtility :: Tablet not assigned to :: " + key, InitializeTeacherJar.getInstance().isLoggingEnabled());
                        }

                        studentSocket.close();
                    }
                }
            }
            catch (Exception e) 
            {
                ApplicationLog.log("CommandQueue :: sendToEveryStudent Exception :: " + e, InitializeTeacherJar.getInstance().isLoggingEnabled());

                studentSocket.close();
            }

            studentSocket = null;
        }
    }

    if (leftOverStudents > 0)
    {
        failedStudents = StudentUtility.m_stripLastChar(failedStudents);

        ApplicationLog.log("SendToEveryStudent :: Some Students Were Not Connected :: " + ErrorCodes.TEACHER_STUDENT_SOCKET_NOT_CONNECTED + InitializeTeacherJar.getInstance().getDelimiter() + failedStudents, InitializeTeacherJar.getInstance().isLoggingEnabled());

        InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + ErrorCodes.TEACHER_STUDENT_SOCKET_NOT_CONNECTED + InitializeTeacherJar.getInstance().getDelimiter() + failedStudents + InitializeTeacherJar.getInstance().getCommandDelimeter()).getBytes());
        InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().flush();         
    }
    else if (leftOverStudents == 0)
    {
        InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + CONSTANTS.SENT_SUCCESSFULLY_TO_ALL + InitializeTeacherJar.getInstance().getDelimiter() + "Sent To All" + InitializeTeacherJar.getInstance().getCommandDelimeter()).getBytes());
        InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().flush();
    }

    StudentUtility.studentCounter = StudentUtility.studentCounter - leftOverStudents;
    }
}
我担心的地方是

1) Loop-使套接字和调用阻塞调用(即accept)的Loop应该放在AsynTask中。 2) SocketTimeout-它应该是最小的,现在是1.2秒。这个的最佳值是多少

这可能有点太多的代码,但我希望解释能有所帮助。
提前感谢。

这是一种向后的设置。想象一下,一个web服务器将连接到所有潜在的客户机以推送一个网页,跳过所有NAT/防火墙问题,这些问题无法扩展,并且在顺序单线程实现中容易出现最重要的延迟,在任何多线程设置中都会浪费资源


我建议切换到传统的客户机-服务器模式,教师是服务器,学生是按需连接的客户机。

这是一种向后设置。想象一下,一个web服务器将连接到所有潜在的客户机以推送一个网页,跳过所有NAT/防火墙问题,这些问题无法扩展,并且在顺序单线程实现中容易出现最重要的延迟,在任何多线程设置中都会浪费资源


我建议切换到传统的客户机-服务器模式,其中教师是服务器,学生是按需连接的客户机。

目前,我有一个垫片来完成这项工作。不过,在我完成软件的正式发布后,我将尝试“收集活动套接字”的方法

无论如何,我对上述代码做了以下更改:

                try
                {   
                    inAddress = InetAddress.getByName(host);

                    if (!inAddress.isReachable())
                    {
                       leftOverStudents++;
                       failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
                       ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
                       continue; 
                    }

                    studentSocket = new Socket(inAddress, port);
                    studentSocket.setSoTimeout(socketTimeout);
                }
我所要做的就是,如果找不到下一个学生,就转到下一个学生。
无论如何,谢谢你的帮助。

目前我有一个垫片要处理。不过,在我完成软件的正式发布后,我将尝试“收集活动套接字”的方法

无论如何,我对上述代码做了以下更改:

                try
                {   
                    inAddress = InetAddress.getByName(host);

                    if (!inAddress.isReachable())
                    {
                       leftOverStudents++;
                       failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
                       ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
                       continue; 
                    }

                    studentSocket = new Socket(inAddress, port);
                    studentSocket.setSoTimeout(socketTimeout);
                }
我所要做的就是,如果找不到下一个学生,就转到下一个学生。
无论如何,谢谢您的帮助。

您是否考虑过存储实际套接字列表而不是ip地址?在你的情况下,我不认为保持开放的套接字是一个问题,因为这个应用程序似乎是在一个设置中使用的-当学生被添加时,创建套接字,当学生离开时,关闭它。这样你就不必不断地建立新的联系(这可能很费时)+1,因为这是我遇到过的最好的“家庭作业”类型的问题之一seen@Drake克拉里斯:谢谢。我在WWW上看到的是,由于内存环境的限制,在基于android的系统中,你不可能打开无数个套接字。将有40名学生同时登录。移动设备b是否能够同时处理多个打开的插座?我一直想做同步广播的事情,但可能…很好。你有没有考虑过存储一个实际套接字列表而不是ip地址?在你的情况下,我不认为保持开放的套接字是一个问题,因为这个应用程序似乎是在一个设置中使用的-当学生被添加时,创建套接字,当学生离开时,关闭它。这样你就不必不断地建立新的联系(这可能很费时)+1,因为这是我遇到过的最好的“家庭作业”类型的问题之一seen@Drake克拉里斯:谢谢。我在WWW上看到的是,由于内存环境的限制,在基于android的系统中,你不可能打开无数个套接字。将有40名学生同时登录。移动设备b是否能够同时处理多个打开的插座?我一直想做同步播放的事情,但可以…好的。嘿,谢谢,我以前也经历过。对于你的方式,我需要为每个学生都有活动套接字,因为学生不能投票给老师的命令,如下一页,上一页,提交答案等,所以老师必须用命令ping他们所有人。该项目有一个庞大的遗留代码库,前开发人员的文档称并发套接字使应用程序崩溃(但我不相信那个家伙)。不过我还没试过。你有没有试过一次打开40多个插座?嘿,谢谢,你以前也经历过。对于你的方式,我需要为每个学生都有活动套接字,因为学生不能投票给老师的命令,如下一页,上一页,提交答案等,所以老师必须用命令ping他们所有人。该项目有一个庞大的遗留代码库,前开发人员的文档称并发套接字使应用程序崩溃(但我不相信那个家伙)。不过我还没试过。您是否曾经尝试过一次打开40多个插座?