阅读(70) (6)

鸿蒙OS DatagramSocket

2022-06-06 16:28:53 更新

DatagramSocket

java.lang.Object

|---java.net.DatagramSocket

public class DatagramSocket
extends Object
implements Closeable

此类表示用于发送和接收数据报包的套接字。

数据报套接字是数据包传递服务的发送点或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。 从一台机器发送到另一台机器的多个数据包可能会以不同的方式路由,并且可能以任何顺序到达。

在可能的情况下,新构建的 DatagramSocket 启用了 SocketOptions#SO_BROADCAST 套接字选项,以允许传输广播数据报。 为了接收广播数据包,应将 DatagramSocket 绑定到通配符地址。 在一些实现中,当 DatagramSocket 绑定到更具体的地址时,也可以接收广播包。

示例:DatagramSocket s = new DatagramSocket(null); s.bind(新 InetSocketAddress(8888)); 相当于:DatagramSocket s = new DatagramSocket(8888); 这两种情况都将创建一个 DatagramSocket 能够在 UDP 端口 8888 上接收广播。

构造函数摘要

修饰符 构造函数 描述
DatagramSocket() 构造一个数据报套接字并将其绑定到本地主机上的任何可用端口。
DatagramSocket(int port) 构造一个数据报套接字并将其绑定到本地主机上的指定端口。
DatagramSocket(int port, InetAddress laddr) 创建一个数据报套接字,绑定到指定的本地地址。
protected DatagramSocket(DatagramSocketImpl impl) 使用指定的 DatagramSocketImpl 创建一个未绑定的数据报套接字。
DatagramSocket(SocketAddress bindaddr) 创建一个数据报套接字,绑定到指定的本地套接字地址。

方法总结

修饰符和类型 方法 描述
void bind(SocketAddress addr) 将此 DatagramSocket 绑定到特定地址和端口。
void close() 关闭此数据报套接字。
void connect(InetAddress address, int port) 将套接字连接到此套接字的远程地址。
void connect(SocketAddress addr) 将此套接字连接到远程套接字地址(IP 地址 + 端口号)。
void disconnect() 断开插座。
boolean getBroadcast() 测试是否启用了 SO_BROADCAST。
DatagramChannel getChannel() 返回与此数据报套接字关联的唯一 DatagramChannel 对象(如果有)。
InetAddress getInetAddress() 返回此套接字连接的地址。
InetAddress getLocalAddress() 获取套接字绑定的本地地址。
int getLocalPort() 返回此套接字绑定到的本地主机上的端口号。
SocketAddress getLocalSocketAddress() 返回此套接字绑定到的端点的地址。
int getPort() 返回此套接字连接到的端口号。
int getReceiveBufferSize() 获取此 DatagramSocket 的 SO_RCVBUF 选项的值,即平台用于此 DatagramSocket 上的输入的缓冲区大小。
SocketAddress getRemoteSocketAddress() 返回此套接字连接到的端点的地址,如果未连接,则返回 null。
boolean getReuseAddress() 测试是否启用了 SO_REUSEADDR。
int getSendBufferSize() 获取此 DatagramSocket 的 SO_SNDBUF 选项的值,即平台用于在此 DatagramSocket 上输出的缓冲区大小。
int getSoTimeout() 检索 SO_TIMEOUT 的设置。
int getTrafficClass() 获取从此 DatagramSocket 发送的数据包的 IP 数据报标头中的流量类别或服务类型。
boolean isBound() 返回套接字的绑定状态。
boolean isClosed() 返回套接字是否关闭。
boolean isConnected() 返回套接字的连接状态。
void receive(DatagramPacket p) 从这个套接字接收一个数据报包。
void send(DatagramPacket p) 从这个套接字发送一个数据报包。
void setBroadcast(boolean on) 启用/禁用 SO_BROADCAST。
static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 为应用程序设置数据报套接字实现工厂。
void setReceiveBufferSize(int size) 将 SO_RCVBUF 选项设置为此 DatagramSocket 的指定值。
void setReuseAddress(boolean on) 启用/禁用 SO_REUSEADDR 套接字选项。
void setSendBufferSize(int size) 将 SO_SNDBUF 选项设置为此 DatagramSocket 的指定值。
void setSoTimeout(int timeout) 使用指定的超时启用/禁用 SO_TIMEOUT,以毫秒为单位。
void setTrafficClass(int tc) 为从此 DatagramSocket 发送的数据报设置 IP 数据报头中的流量类别或服务类型八位字节。
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

构造函数详细信息

DatagramSocket

public DatagramSocket() throws SocketException

构造一个数据报套接字并将其绑定到本地主机上的任何可用端口。 套接字将绑定到 InetAddress#isAnyLocalAddress 地址,这是内核选择的 IP 地址。

如果存在安全管理器,则首先调用其 checkListen 方法,并以 0 作为其参数,以确保允许该操作。 这可能会导致 SecurityException。

Throws:

Throw名称 Throw描述
SocketException 如果套接字无法打开,或者套接字无法绑定到指定的本地端口。
SecurityException 如果安全管理器存在并且其 checkListen 方法不允许该操作。

DatagramSocket

protected DatagramSocket(DatagramSocketImpl impl)

使用指定的 DatagramSocketImpl 创建一个未绑定的数据报套接字。

参数:

参数名称 参数描述
impl 子类希望在 DatagramSocket 上使用的 DatagramSocketImpl 的实例。

DatagramSocket

public DatagramSocket(SocketAddress bindaddr) throws SocketException

创建一个数据报套接字,绑定到指定的本地套接字地址。

如果地址为空,则创建一个未绑定的套接字。

如果有安全管理器,首先调用它的 checkListen 方法,并使用来自套接字地址的端口作为其参数,以确保允许该操作。 这可能会导致 SecurityException。

参数:

参数名称 参数描述
bindaddr 要绑定的本地套接字地址,对于未绑定的套接字,则为 null。

Throws:

Throw名称 Throw描述
SocketException 如果套接字无法打开,或者套接字无法绑定到指定的本地端口。
SecurityException 如果安全管理器存在并且其 checkListen 方法不允许该操作。

DatagramSocket

public DatagramSocket(int port) throws SocketException

构造一个数据报套接字并将其绑定到本地主机上的指定端口。 套接字将绑定到 InetAddress#isAnyLocalAddress 地址,这是内核选择的 IP 地址。

如果有安全管理器,首先调用它的 checkListen 方法,并将端口参数作为其参数,以确保允许该操作。 这可能会导致 SecurityException。

参数:

参数名称 参数描述
port 要使用的端口。

Throws:

Throw名称 Throw描述
SocketException 如果套接字无法打开,或者套接字无法绑定到指定的本地端口。
SecurityException 如果安全管理器存在并且其 checkListen 方法不允许该操作。

DatagramSocket

public DatagramSocket(int port, InetAddress laddr) throws SocketException

创建一个数据报套接字,绑定到指定的本地地址。 本地端口必须介于 0 和 65535 之间(含)。 如果 IP 地址是 0.0.0.0,则套接字将绑定到 InetAddress#isAnyLocalAddress 地址,这是内核选择的 IP 地址。

如果有安全管理器,首先调用它的 checkListen 方法,并将端口参数作为其参数,以确保允许该操作。 这可能会导致 SecurityException。

参数:

参数名称 参数描述
port 要使用的本地端口
laddr 要绑定的本地地址

Throws:

Throw名称 Throw描述
SocketException 如果套接字无法打开,或者套接字无法绑定到指定的本地端口。
SecurityException 如果安全管理器存在并且其 checkListen 方法不允许该操作。

Method Detail

bind

public void bind(SocketAddress addr) throws SocketException

将此 DatagramSocket 绑定到特定地址和端口。

如果地址为空,那么系统将选择一个临时端口和一个有效的本地地址来绑定套接字。

参数:

参数名称 参数描述
addr 要绑定的地址和端口。

Throws:

Throw名称 Throw描述
SocketException 如果在绑定期间发生任何错误,或者套接字已经绑定。
SecurityException 如果安全管理器存在并且其 checkListen 方法不允许该操作。
IllegalArgumentException 如果 addr 是此套接字不支持的 SocketAddress 子类。

connect

public void connect(InetAddress address, int port)

将套接字连接到此套接字的远程地址。当套接字连接到远程地址时,数据包只能发送到该地址或从该地址接收。默认情况下,未连接数据报套接字。

如果套接字连接到的远程目标不存在,或者无法到达,并且如果已接收到该地址的 ICMP 目标无法到达数据包,则后续调用 send 或 receive 可能会抛出 PortUnreachableException。请注意,不能保证会引发异常。

如果已安装安全管理器,则调用它来检查对远程地址的访问。具体来说,如果给定地址是 InetAddress#isMulticastAddress,则使用给定地址调用安全管理器的 checkMulticast 方法。否则,使用给定的地址和端口调用安全管理器的 checkConnect 和 checkAccept 方法,以验证是否允许分别发送和接收数据报。

当套接字连接时,接收和发送不会对传入和传出的数据包执行任何安全检查,除了匹配数据包和套接字的地址和端口。在发送操作中,如果设置了数据包的地址并且数据包的地址和套接字的地址不匹配,则会抛出 IllegalArgumentException。连接到多播地址的套接字只能用于发送数据包。

参数:

参数名称 参数描述
address 套接字的远程地址
port 套接字的远程端口。

Throws:

Throw名称 Throw描述
IllegalArgumentException 如果地址为空,或者端口超出范围。
SecurityException 如果已安装安全管理器并且它不允许访问给定的远程地址

connect

public void connect(SocketAddress addr) throws SocketException

将此套接字连接到远程套接字地址(IP 地址 + 端口号)。

如果给定 InetSocketAddress,则此方法的行为就像使用给定的套接字地址 IP 地址和端口号调用 connect(InetAddress,int)。

参数:

参数名称 参数描述
addr 远程地址。

Throws:

Throw名称 Throw描述
SocketException 如果连接失败
IllegalArgumentException 如果 addr 为 null,或者 addr 是此套接字不支持的 SocketAddress 子类
SecurityException 如果已安装安全管理器并且它不允许访问给定的远程地址

disconnect

public void disconnect()

断开插座。 如果套接字已关闭或未连接,则此方法无效。

isBound

public boolean isBound()

返回套接字的绑定状态。

如果套接字在关闭之前已绑定,则此方法将在套接字关闭后继续返回 true。

返回:

如果套接字成功绑定到地址,则为 true

isConnected

public boolean isConnected()

返回套接字的连接状态。

如果套接字在关闭之前已连接,则此方法将在套接字关闭后继续返回 true。

返回:

如果套接字成功连接到服务器,则为 true

getInetAddress

public InetAddress getInetAddress()

返回此套接字连接的地址。 如果套接字未连接,则返回 null。

如果套接字在关闭之前已连接,则此方法将在套接字关闭后继续返回已连接的地址。

返回:

此套接字连接到的地址。

getPort

public int getPort()

返回此套接字连接到的端口号。 如果套接字未连接,则返回 -1。

如果套接字在关闭之前已连接,则此方法将在套接字关闭后继续返回连接的端口号。

返回:

此套接字连接到的端口号。

getRemoteSocketAddress

public SocketAddress getRemoteSocketAddress()

返回此套接字连接到的端点的地址,如果未连接,则返回 null。

如果套接字在关闭之前已连接,则此方法将在套接字关闭后继续返回已连接的地址。

返回:

表示此套接字的远程端点的 SocketAddress,如果尚未连接,则为 null。

getLocalSocketAddress

public SocketAddress getLocalSocketAddress()

返回此套接字绑定到的端点的地址。

返回:

一个 SocketAddress 表示此套接字的本地端点,如果它已关闭或尚未绑定,则为 null。

send

public void send(DatagramPacket p) throws IOException

从这个套接字发送一个数据报包。 DatagramPacket 包括指示要发送的数据、其长度、远程主机的 IP 地址和远程主机上的端口号的信息。

如果有安全管理器,并且套接字当前未连接到远程地址,则此方法首先执行一些安全检查。 首先,如果 p.getAddress().isMulticastAddress() 为真,则此方法以 p.getAddress() 作为参数调用安全管理器的 checkMulticast 方法。 如果该表达式的评估结果为假,则此方法将使用参数 p.getAddress().getHostAddress() 和 p.getPort() 调用安全管理器的 checkConnect 方法。 如果不允许该操作,则对安全管理器方法的每次调用都可能导致 SecurityException。

参数:

参数名称 参数描述
p 要发送的 DatagramPacket。

Throws:

Throw名称 Throw描述
IOException 如果发生 I/O 错误。
SecurityException 如果存在安全管理器并且其 checkMulticast 或 checkConnect 方法不允许发送。
PortUnreachableException 如果套接字连接到当前无法到达的目的地,则可能会抛出。 请注意,不能保证会引发异常。
IllegalBlockingModeException 如果此套接字具有关联的通道,并且该通道处于非阻塞模式。
IllegalArgumentException 如果套接字已连接,并且连接地址和数据包地址不同。

receive

public void receive(DatagramPacket p) throws IOException

从这个套接字接收一个数据报包。 当此方法返回时,DatagramPacket 的缓冲区被接收到的数据填充。 数据报包还包含发送者的 IP 地址和发送者机器上的端口号。

此方法阻塞,直到接收到数据报。 数据报包对象的长度字段包含接收到的消息的长度。 如果消息长于数据包的长度,则消息被截断。

如果有安全管理器,如果安全管理器的 checkAccept 方法不允许,则无法接收数据包。

参数:

参数名称 参数描述
p 放置传入数据的 DatagramPacket。

Throws:

Throw名称 Throw描述
IOException 如果发生 I/O 错误。
SocketTimeoutException 如果之前调用了 setSoTimeout 并且超时已过期。
PortUnreachableException 如果套接字连接到当前无法到达的目的地,则可能会抛出。 请注意,不能保证会引发异常。
IllegalBlockingModeException 如果此套接字具有关联的通道,并且该通道处于非阻塞模式。

getLocalAddress

public InetAddress getLocalAddress()

获取套接字绑定的本地地址。

如果有安全管理器,首先调用它的 checkConnect 方法,并以主机地址和 -1 作为其参数,以查看是否允许该操作。

返回:

套接字绑定到的本地地址,如果套接字已关闭,则为 null,或者如果套接字未绑定或安全管理器 checkConnect 方法不允许操作,则表示 InetAddress#isAnyLocalAddress 地址的 InetAddress

getLocalPort

public int getLocalPort()

返回此套接字绑定到的本地主机上的端口号。

返回:

此套接字绑定到的本地主机上的端口号,如果套接字已关闭,则为 -1,如果尚未绑定,则为 0。

setSoTimeout

public void setSoTimeout(int timeout) throws SocketException

使用指定的超时启用/禁用 SO_TIMEOUT,以毫秒为单位。 将此选项设置为非零超时后,对此 DatagramSocket 的 receive() 调用将仅阻塞此时间量。 如果超时到期,则会引发 java.net.SocketTimeoutException,尽管 DatagramSocket 仍然有效。 必须在进入阻塞操作之前启用该选项才能生效。 超时必须 > 0。超时为零被解释为无限超时。

参数:

参数名称 参数描述
timeout 以毫秒为单位的指定超时。

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

getSoTimeout

public int getSoTimeout() throws SocketException

检索 SO_TIMEOUT 的设置。 返回 0 表示该选项被禁用(即无限超时)。

返回:

SO_TIMEOUT 的设置

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

setSendBufferSize

public void setSendBufferSize(int size) throws SocketException

将 SO_SNDBUF 选项设置为此 DatagramSocket 的指定值。 网络实现使用 SO_SNDBUF 选项作为调整底层网络 I/O 缓冲区大小的提示。 网络实现也可以使用 SO_SNDBUF 设置来确定可以在此套接字上发送的数据包的最大大小。

由于 SO_SNDBUF 是一个提示,想要验证缓冲区大小的应用程序应该调用 getSendBufferSize()。

当发送速率很高时,增加缓冲区大小可能允许网络实现将多个传出数据包排队。

注意:如果使用 send(java.net.DatagramPacket) 发送大于 SO_SNDBUF 设置的 DatagramPacket,则发送或丢弃数据包是特定于实现的。

参数:

参数名称 参数描述
size 设置发送缓冲区大小的大小。 该值必须大于 0。

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。
IllegalArgumentException 如果值为 0 或为负数。

getSendBufferSize

public int getSendBufferSize() throws SocketException

获取此 DatagramSocket 的 SO_SNDBUF 选项的值,即平台用于在此 DatagramSocket 上输出的缓冲区大小。

返回:

此 DatagramSocket 的 SO_SNDBUF 选项的值

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

setReceiveBufferSize

public void setReceiveBufferSize(int size) throws SocketException

将 SO_RCVBUF 选项设置为此 DatagramSocket 的指定值。 网络实现使用 SO_RCVBUF 选项作为调整底层网络 I/O 缓冲区大小的提示。 网络实现也可以使用 SO_RCVBUF 设置来确定可以在此套接字上接收的数据包的最大大小。

因为 SO_RCVBUF 是一个提示,所以想要验证缓冲区设置为多大大小的应用程序应该调用 getReceiveBufferSize()。

当数据包到达的速度快于使用接收(java.net.DatagramPacket)接收的速度时,增加 SO_RCVBUF 可能允许网络实现缓冲多个数据包。

注意:是否可以接收到大于 SO_RCVBUF 的数据包是特定于实现的。

参数:

参数名称 参数描述
size 设置接收缓冲区大小的大小。 该值必须大于 0。

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。
IllegalArgumentException 如果值为 0 或为负数。

getReceiveBufferSize

public int getReceiveBufferSize() throws SocketException

获取此 DatagramSocket 的 SO_RCVBUF 选项的值,即平台用于此 DatagramSocket 上的输入的缓冲区大小。

返回:

此 DatagramSocket 的 SO_RCVBUF 选项的值

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

setReuseAddress

public void setReuseAddress(boolean on) throws SocketException

启用/禁用 SO_REUSEADDR 套接字选项。

对于 UDP 套接字,可能需要将多个套接字绑定到同一个套接字地址。 这通常用于接收多播数据包(请参阅 MulticastSocket)。 如果在使用 bind(java.net.SocketAddress) 绑定套接字之前启用了 SO_REUSEADDR 套接字选项,则 SO_REUSEADDR 套接字选项允许将多个套接字绑定到同一个套接字地址。

注意:并非所有现有平台都支持此功能,因此是否忽略此选项取决于具体实现。 但是,如果不支持,则 getReuseAddress() 将始终返回 false。

创建 DatagramSocket 时,SO_REUSEADDR 的初始设置被禁用。

未定义套接字绑定后启用或禁用 SO_REUSEADDR 时的行为。

参数:

参数名称 参数描述
on 是否启用或禁用

Throws:

Throw名称 Throw描述
SocketException 如果启用或禁用 SO_RESUEADDR 套接字选项发生错误,或者套接字已关闭。

getReuseAddress

public boolean getReuseAddress() throws SocketException

测试是否启用了 SO_REUSEADDR。

返回:

一个布尔值,指示是否启用 SO_REUSEADDR。

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

setBroadcast

public void setBroadcast(boolean on) throws SocketException

启用/禁用 SO_BROADCAST。

某些操作系统可能要求以实现特定权限启动 Java 虚拟机以启用此选项或发送广播数据报。

参数:

参数名称 参数描述
on 是否开启广播。

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

getBroadcast

public boolean getBroadcast() throws SocketException

测试是否启用了 SO_BROADCAST。

返回:

一个布尔值,指示是否启用 SO_BROADCAST。

Throws:

Throw名称 Throw描述
SocketException 如果底层协议有错误,例如 UDP 错误。

setTrafficClass

public void setTrafficClass(int tc) throws SocketException

为从此 DatagramSocket 发送的数据报设置 IP 数据报头中的流量类别或服务类型八位字节。 由于底层网络实现可能会忽略此值,因此应用程序应将其视为提示。

tc 必须在 0 <= tc <= 255 范围内,否则将抛出 IllegalArgumentException。

笔记:

对于 Internet 协议 v4,该值由一个整数组成,其中最低有效 8 位表示套接字发送的 IP 数据包中 TOS 八位字节的值。 RFC 1349 定义 TOS 值如下:

  • IPTOS_LOWCOST (0x02)
  • IPTOS_RELIABILITY (0x04)
  • IPTOS_THROUGHPUT (0x08)
  • IPTOS_LOWDELAY (0x10)

最后一个低位总是被忽略,因为它对应于 MBZ(必须为零)位。

设置优先级字段中的位可能会导致 SocketException 指示不允许该操作。

对于 Internet 协议 v6,tc 是放置在 IP 标头的 sin6_flowinfo 字段中的值。

参数:

参数名称 参数描述
tc 位集的 int 值。

Throws:

Throw名称 Throw描述
SocketException 如果设置流量类别或服务类型时出错

getTrafficClass

public int getTrafficClass() throws SocketException

获取从此 DatagramSocket 发送的数据包的 IP 数据报标头中的流量类别或服务类型。

由于底层网络实现可能会忽略使用 setTrafficClass(int) 设置的流量类或服务类型,因此此方法可能返回与之前使用此 DatagramSocket 上的 setTrafficClass(int) 方法设置的值不同的值。

返回:

已设置的流量类别或服务类型

Throws:

Throw名称 Throw描述
SocketException 如果获取流量类别或服务类型值时出错。

close

public void close()

关闭此数据报套接字。

当前在此套接字上的接收(java.net.DatagramPacket)中阻塞的任何线程都将抛出 SocketException。

如果此套接字具有关联的通道,则该通道也将关闭。

指定者:

在接口 AutoCloseable 中关闭

指定者:

在接口Closeable中关闭

isClosed

public boolean isClosed()

返回套接字是否关闭。

返回:

如果套接字已关闭,则为 true

getChannel

public DatagramChannel getChannel()

返回与此数据报套接字关联的唯一 DatagramChannel 对象(如果有)。

当且仅当通道本身是通过 DatagramChannel.open 方法创建时,数据报套接字才会具有通道。

返回:

与此数据报套接字关联的数据报通道,如果此套接字不是为通道创建的,则为 null

setDatagramSocketImplFactory

public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) throws IOException

为应用程序设置数据报套接字实现工厂。 工厂只能指定一次。

当应用程序创建新的数据报套接字时,会调用套接字实现工厂的 createDatagramSocketImpl 方法来创建实际的数据报套接字实现。

除非已经设置了工厂,否则将 null 传递给方法是无操作的。

如果有安全管理器,该方法首先调用安全管理器的 checkSetFactory 方法,确保操作被允许。 这可能会导致 SecurityException。

参数:

参数名称 参数描述
fac 想要的工厂。

Throws:

Throw名称 Throw描述
IOException 如果在设置数据报套接字工厂时发生 I/O 错误。
SocketException 如果工厂已经定义。
SecurityException 如果存在安全管理器并且其 checkSetFactory 方法不允许该操作。