如何在一段时间后关闭 UDP 接收套接字?
How to close UDP receiving socket after a period of time?
我这样新建一个话题
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();
我想接收返回消息的列表,但似乎此尝试永远不会进行到最后且此套接字永远不会关闭。下次我想绑定这个端口时可能会出现一些问题。
如何确保此端口在一段时间后关闭。
如果您希望在您的时间限制内完成对 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)。
我这样新建一个话题
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();
我想接收返回消息的列表,但似乎此尝试永远不会进行到最后且此套接字永远不会关闭。下次我想绑定这个端口时可能会出现一些问题。 如何确保此端口在一段时间后关闭。
如果您希望在您的时间限制内完成对 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)。