gpt4 book ai didi

java - Java中的UDP认为UDP有 "connections"

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:42:35 26 4
gpt4 key购买 nike

Java中的UDP认为UDP有“连接”。这让我感到惊讶,因为我有 C 语言背景,在这种背景下我一直使用 UDP 作为一种即发即弃的协议(protocol)。

在 Java 中测试 UDP 时,我注意到如果远程 UDP 端口未监听,我会在 尝试发送任何内容之前在 Java 中收到错误。

为了能够判断远程 UDP 端口是否正在监听,Java 做了什么(没有我要求它这样做)?

(下面的代码在套接字的接收线程中运行。发送在不同的线程中完成。)

    try {
socket = new DatagramSocket(udpPort);
socket.connect(udpAddr, udpPort);
} catch (SocketException e) {
Log.d(TAG, "disconnected", e);
}
...
while (true) {
// TODO: don't create a new datagram for each iteration
DatagramPacket packet = new DatagramPacket(new byte[BUF_SIZE], BUF_SIZE);
try {
socket.receive(packet); // line 106
} catch (IOException e) {
Log.d(TAG, "couldn't recv", e);
}
...

如果远程套接字未监听,则会产生以下错误。

java.net.PortUnreachableException:
at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:556)
at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
at java.net.PlainDatagramSocketImpl.doRecv(PlainDatagramSocketImpl.java:161)
at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:169)
at java.net.DatagramSocket.receive(DatagramSocket.java:253)
at com.example.mypkg.MyClass.run(MyClass.java:106)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNREFUSED (Connection refused)
at libcore.io.Posix.recvfromBytes(Native Method)
at libcore.io.Posix.recvfrom(Posix.java:131)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
...

最佳答案

首先,很明显这不是使用真正的 Java 实现的。 “libcore.io”包不是 Java SE 库的一部分。这些是 Android 堆栈跟踪。 (这不会改变任何东西......但它可以。)

好的,让我们从异常开始。 java.net.PortUnreachableException 的 javadoc说:

"Signals that an ICMP Port Unreachable message has been received on a connected datagram."

对于 DatagramSocket.connect(...) :

"If the remote destination to which the socket is connected does not exist, or is otherwise unreachable, and if an ICMP destination unreachable packet has been received for that address, then a subsequent call to send or receive may throw a PortUnreachableException. Note, there is no guarantee that the exception will be thrown."

这就是我认为发生的事情。在创建 incoming 之前套接字,客户端系统上的某些东西已在该端口上向服务器发送了一个 UDP 数据包,并且服务器已响应 ICMP 端口无法访问。然后创建并连接套接字,然后调用 receive .这是一个 recvfrom系统调用和网络堆栈以 ECONREFUSED 错误代码响应...... Java 将其转换为 PortUnreachableException ,

那么这是否意味着 UDP 是面向连接的呢?

不是真的,海事组织。它只是报告它收到了一条 ICMP 消息以响应之前发生的事情

connect呢?方法,以及“连接套接字”/“连接数据报”用语?

IMO,这只是一些笨拙的措辞。 “连接”实际上只是指数据报套接字已绑定(bind)到特定的远程地址和端口...这样您就可以在不指定 IP 和端口的情况下发送和接收数据报<支持>1

这些“连接”非常脆弱,当然不等于使 UDP“面向连接”。

What does Java do (without me asking it to) in order to be able to tell whether a remote UDP port is listening?

它没有做任何事情。 Java 只是报告来自先前 ICMP 消息的信息。


1 - 实际上,它的意义远不止于此。例如,绑定(bind)告诉客户端操作系统缓冲来自该主机/端口的 UDP 数据包,并将 UDP 数据包(和 ICMP 通知)路由到应用程序。它还告诉它不要使用 ICMP 端口无法访问进行响应。

关于java - Java中的UDP认为UDP有 "connections",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33260478/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com