MulticastSocket поддерживает функцию прослушивания

Я работаю над приложениями для сокетов на основе UDP, и здесь у меня есть несколько вопросов о том, как реализовать функцию прослушивания на принимающей стороне.

  1. Ниже приведен хороший способ позволить сокету на стороне приема продолжать прослушивание на стороне сервера? Предположим, я не знаю, когда серверная сторона отправит пакет на принимающую сторону, поэтому мне нужно, чтобы функция приема всегда была включена. Будет ли он пропущен или каким-то образом сломается цикл while (true)? Если да, то как «повторно подключиться» и снова оживить цикл прослушивания?

    while(true){
    
        try{
         if ( udpsocket_receiving.isClosed() || !udpsocket_receiving.isConnected() ) {
    
                serverAddress = InetAddress.getByName(SERVERIP);
                udpsocket_receiving = new MulticastSocket(SERVERPORT) ;
                udpsocket_receiving.joinGroup(serverAddress);
                udpsocket_receiving.setSoTimeout(10000);
            }
            udpsocket_receiving.receive(recpacket);
            // Block of code to do with the packet
    
        } catch ( SocketTimeoutException e ) {
             // What suppose to do here if I catch this exception?
        } finally {
             udpsocket_receiving.close();
             continue;
        }
    }
    
  2. Может ли вышеописанный метод уже решить, если у меня нет доступа в Интернет в течение определенного времени, предположим, что метод всегда будет перехватывать правильное исключение SocketTimeoutException? Но когда доступ в Интернет возобновится позже, смогу ли я продолжить прослушивание, когда придет пакет?

  3. Предположим, я получил первый пакет от отправителя и выполнил код, но отправитель отправил второй пакет в это время, я пропущу пакет? Так как цикл while на первом пакете не заканчивается.

  4. Ниже приведен хороший подход, чтобы вручную закрыть сокет и «повторно подключить» его снова? Будет ли он каким-то образом связывать порт и не сможет снова использовать тот же порт для нового объекта? И если это блок правильного кода, я должен поместить их внутрь SocketTimeoutException в вопросе один?

        udpsocket_receiving.leaveGroup(serverAddress);
        udpsocket_receiving.disconnect();
        udpsocket_receiving.close();
        udpsocket_receiving = new MulticastSocket(SERVERPORT) ;
        udpsocket_receiving.setSoTimeout(10000);
        udpsocket_receiving.joinGroup(serverAddress);
    

person Sean    schedule 13.07.2017    source источник


Ответы (1)


Нет. Вы никогда не подключаете сокет, поэтому dpsocket_receiving.isConnected() никогда не будет истинным. Вам не нужна вся эта закрытая/открытая чепуха внутри цикла чтения. Единственный человек, который когда-либо закроет сокет, это вы. SocketTimeoutException означает, что ни одна дейтаграмма не была получена в течение периода ожидания чтения. Что вы будете делать с этим, зависит от вас, может быть, ничего, но это не значит, что вы должны закрыть и повторно инициализировать сокет. Переделывание всего этого не решит проблему подключения к Интернету.

Единственный способ, которым вы обычно пропускаете пакеты, - это их отбрасывание, но закрытие и повторное открытие сокета предоставляет окно, в котором это обязательно произойдет. Не делай этого.

При закрытии сокета все, что вам нужно сделать, это закрыть его. Выход из всех его многоадресных групп происходит автоматически, как и отключение, и, поскольку вы никогда не подключали его, нет необходимости отключать его в первую очередь.

person user207421    schedule 13.07.2017
comment
спасибо за ответ, поэтому, основываясь на вашем комментарии, мне просто нужно удалить блок finally из цикла while и переместить код инициализации туда, где он запускается только один раз, я прав? - person Sean; 13.07.2017
comment
Кроме того, как вы сказали, повторение всего этого не решит проблему подключения к Интернету, поэтому, если после отключения подключения к Интернету сокет больше не будет прослушиваться, даже если подключение восстановится? - person Sean; 13.07.2017
comment
Сокет остается действительным независимо от подключения к Интернету. - person user207421; 13.07.2017