一段时间后如何关闭UDP接收套接字?

时间:2016-03-14 11:59:56

标签: java android sockets 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();

我想收到一条返回消息的列表,但似乎这个尝试永远不会去到finally,这个套接字永远不会关闭。下次我想绑定此端口时可能会导致一些问题。 如何在一段时间后确保此端口关闭。

1 个答案:

答案 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)。