如果我只是发送到 UDP 套接字但没有收到会发生什么
What happens if I just send to UDP socket and dont recive
我有一个 UDP 客户端的最小实现:
final class UdpClient {
private final DatagramSocket socket;
private final InetAddress address;
private final Integer port;
UdpClient(URI location) {
port = location.getPort();
try {
socket = new DatagramSocket();
address = InetAddress.getByName(location.getHost());
} catch (SocketException | UnknownHostException e) {
throw new RuntimeException("Error setting up UDP connection", e);
}
}
void sendData(String msg) {
byte[] buf = msg.getBytes();
DatagramPacket packet
= new DatagramPacket(buf, buf.length, address, port);
try {
socket.send(packet);
} catch (IOException e) {
LOG.warn("Failed to send data {}", e.getMessage());
}
}
public void close() {
socket.close();
}
}
现在我开始怀疑这是否是一个有效的暗示,因为我从未收到回复。我不关心回复会有什么后果?在没有明确得到回复的情况下,这甚至是一个有效的实现吗?
更新
我提出问题的原因是,我担心如果我从不进行显式接收,可能会有一些底层缓冲区正在填满。此客户端可用于发送回复的服务器或未发送回复的服务器。
Now I'm starting to question if this is a valid impl since I never receive the reply.
这是一个有效的实现。
What are the consequences of me not caring about the reply?
唯一真正的后果是客户端将无法判断它发送数据包的服务器是否正在接收它们。
你可能可以接受。
And is this even a valid impl without explicitly getting a reply?
从Java和UDP规范的角度来看是有效的。
这是否有意义...我们无法判断...因为您还没有解释为什么要这样做。
The reason for my questions is that I'm worried that there might be some underlying buffer that is just filling up if I never do an explicit receive.
从你的意思来说,没有...。可能有一个out-going数据包缓冲区,它可能会溢出,但这只会发生在某些类型的网络link上,并且不会因为没有收到回复而触发。 (如果 link 很慢并且不能足够快地发送数据,则可能会发生这种情况。但是如果发生这种情况,客户端的 OS 应该 悄悄地丢弃数据包缓冲区。您的应用程序不会知道发生了什么。)
但是,您的实施存在一些问题:
问题 #1
address = InetAddress.getByName(location.getHost());
您忽略了 URI 的“协议”。因此,例如,如果 URI 是一个用于托管“http”服务的资源,您最终会向(通常)端口 80 上的主机发送 UDP 数据包。但是 Web 服务器不会在端口 80 上侦听 UDP 数据包。您发送的数据包很可能会被忽略。
问题 #2
throw new RuntimeException("Error setting up UDP connection", e);
UDP 是无连接的,因此您没有建立连接。此外,此时还没有数据包实际发送到远程主机。您实际做的唯一一件事是尝试将远程服务器的 DNS 名称解析为 IP 地址。
问题 #3
LOG.warn("Failed to send data {}", e.getMessage());
的确,您确实到了发送数据包失败的地步。然而,如果你没有得到这个异常,你唯一知道的就是你已经让数据包开始它的旅程。您甚至不知道数据包是否已经离开客户端计算机。
我有一个 UDP 客户端的最小实现:
final class UdpClient {
private final DatagramSocket socket;
private final InetAddress address;
private final Integer port;
UdpClient(URI location) {
port = location.getPort();
try {
socket = new DatagramSocket();
address = InetAddress.getByName(location.getHost());
} catch (SocketException | UnknownHostException e) {
throw new RuntimeException("Error setting up UDP connection", e);
}
}
void sendData(String msg) {
byte[] buf = msg.getBytes();
DatagramPacket packet
= new DatagramPacket(buf, buf.length, address, port);
try {
socket.send(packet);
} catch (IOException e) {
LOG.warn("Failed to send data {}", e.getMessage());
}
}
public void close() {
socket.close();
}
}
现在我开始怀疑这是否是一个有效的暗示,因为我从未收到回复。我不关心回复会有什么后果?在没有明确得到回复的情况下,这甚至是一个有效的实现吗?
更新
我提出问题的原因是,我担心如果我从不进行显式接收,可能会有一些底层缓冲区正在填满。此客户端可用于发送回复的服务器或未发送回复的服务器。
Now I'm starting to question if this is a valid impl since I never receive the reply.
这是一个有效的实现。
What are the consequences of me not caring about the reply?
唯一真正的后果是客户端将无法判断它发送数据包的服务器是否正在接收它们。
你可能可以接受。
And is this even a valid impl without explicitly getting a reply?
从Java和UDP规范的角度来看是有效的。
这是否有意义...我们无法判断...因为您还没有解释为什么要这样做。
The reason for my questions is that I'm worried that there might be some underlying buffer that is just filling up if I never do an explicit receive.
从你的意思来说,没有...。可能有一个out-going数据包缓冲区,它可能会溢出,但这只会发生在某些类型的网络link上,并且不会因为没有收到回复而触发。 (如果 link 很慢并且不能足够快地发送数据,则可能会发生这种情况。但是如果发生这种情况,客户端的 OS 应该 悄悄地丢弃数据包缓冲区。您的应用程序不会知道发生了什么。)
但是,您的实施存在一些问题:
问题 #1
address = InetAddress.getByName(location.getHost());
您忽略了 URI 的“协议”。因此,例如,如果 URI 是一个用于托管“http”服务的资源,您最终会向(通常)端口 80 上的主机发送 UDP 数据包。但是 Web 服务器不会在端口 80 上侦听 UDP 数据包。您发送的数据包很可能会被忽略。
问题 #2
throw new RuntimeException("Error setting up UDP connection", e);
UDP 是无连接的,因此您没有建立连接。此外,此时还没有数据包实际发送到远程主机。您实际做的唯一一件事是尝试将远程服务器的 DNS 名称解析为 IP 地址。
问题 #3
LOG.warn("Failed to send data {}", e.getMessage());
的确,您确实到了发送数据包失败的地步。然而,如果你没有得到这个异常,你唯一知道的就是你已经让数据包开始它的旅程。您甚至不知道数据包是否已经离开客户端计算机。