2016-03-14 2 views
0

я новый поток как этотКак закрыть приемное гнездо UDP через некоторое время?

 new Thread(new Runnable() { 
     @Override 
     public void run() { 
      DatagramSocket udpSocket = null; 

      try { 
       udpSocket = new DatagramSocket(null); 
       udpSocket.setReuseAddress(true); 
       udpSocket.setBroadcast(true); 
       udpSocket.bind(new InetSocketAddress(BIND_PORT)); 


       InetAddress ipAddress = InetAddress.getByName(BROADCAST); 
       DatagramPacket udpSendPacket = new DatagramPacket(sendMessage, sendMessage.length, ipAddress, SEND_PORT); 

       // udp send 
       udpSocket.send(udpSendPacket); 


       // udp receive 
       byte[] receiveMessage = new byte[100]; 
       DatagramPacket udpReceivePacket = new DatagramPacket(receiveMessage, receiveMessage.length); 

       long startTime = System.currentTimeMillis(); 
       while ((System.currentTimeMillis()-startTime) < 5000) { 
        udpSocket.receive(udpReceivePacket); 
        Log.v(TAG, new String(receiveMessage, 0, udpReceivePacket.getLength())); 

       } 
       udpSocket.close(); 
       Log.v(TAG, "udp: close"); 
      } catch (Exception e) { 
       Log.e(TAG, e.toString()); 
       e.printStackTrace(); 
      } finally { 
       if (udpSocket != null) { 
        udpSocket.close(); 
        Log.v(TAG, "udp: close"); 
       } 
      } 
     } 
    }).start(); 

Я хочу, чтобы получить список возвращенного сообщения, но, кажется, это старается не идти в конце концов, и этот сокет никогда не закрывается. Это может вызвать некоторые проблемы в следующий раз, когда я хочу привязать этот порт. Как я могу убедиться, что этот порт закрыт через некоторое время.

+0

Почему вы ожидаете выхода цикла while? –

+0

Я знаю, что этого не произойдет, поэтому мне нужен какой-то метод, чтобы он вышел. Я пробовал long startTime = System.currentTimeMillis(); while (true && (System.currentTimeMillis() - startTime) <5000) { }, но не работает. –

+0

Да, вы могли бы использовать что-то подобное. Почему это не работает для вас? –

ответ

0

Если вы хотите, чтобы ваш звонок до DatagramSocket.receive закончил с вашим лимитом, вам необходимо позвонить в DatagramSocket.setSoTimeout(int), который устанавливает тайм-аут в операции чтения.

Ваш while цикл будет выглядеть примерно так:

long startMillis = System.currentTimeMillis(); 
long endMillis = startMillis + 100; 
long currentMillis; 
try { 
    while ((currentMillis = System.currentTimeMillis()) < endMillis) { 
    long soTimeout = endMillis - currentMillis; 
    udpSocket.setSoTimeout((int) soTimeout); 
    updSocket.receive(udpReceivePacket); 
    // ... 
    } 
} catch (SocketTimeoutException e) { 
    // This means that the socket timed out without receiving data in time. 
    // You can still read from the socket again (although you probably 
    // want to increase the timeout again). 
} 

Обратите внимание, что System.currentTimeMillis() не на самом деле предназначен для измерения прошло время, хотя - это время стены. Вместо этого вы должны использовать System.nanoTime(), который предназначен для этой цели (очевидно, вам нужно разделить время на 1e6).

+0

Большое спасибо за этот метод и отличное объяснение! –

Смежные вопросы