public class DatagramSocket extends Object implements Closeable
数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。 从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。
在可能的情况下,新构建的DatagramSocket
启用了SO_BROADCAST
套接字选项,以允许广播数据报的传输。 为了接收广播数据包,DatagramSocket应该绑定到通配符地址。 在一些实现中,当DatagramSocket绑定到更具体的地址时,也可以接收广播分组。
示例: DatagramSocket s = new DatagramSocket(null); s.bind(new InetSocketAddress(8888));
其中相当于: DatagramSocket s = new DatagramSocket(8888);
这两种情况都将创建一个DatagramSocket,可以在UDP端口8888上接收广播。
DatagramPacket
, DatagramChannel
Modifier | Constructor and Description |
---|---|
|
DatagramSocket()
构造数据报套接字并将其绑定到本地主机上的任何可用端口。
|
protected |
DatagramSocket(DatagramSocketImpl impl)
使用指定的DatagramSocketImpl创建一个未绑定的数据报套接字。
|
|
DatagramSocket(int port)
构造数据报套接字并将其绑定到本地主机上的指定端口。
|
|
DatagramSocket(int port, InetAddress laddr)
创建一个数据报套接字,绑定到指定的本地地址。
|
|
DatagramSocket(SocketAddress bindaddr)
创建一个数据报套接字,绑定到指定的本地套接字地址。
|
Modifier and Type | Method and Description |
---|---|
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数据报头中设置流量类别或服务类型的八位字节。
|
public DatagramSocket() throws SocketException
wildcard
地址,一个由内核选择的IP地址。
如果有一个安全管理器,它的checkListen
方法首先被调用为0作为参数,以确保操作是允许的。 这可能会导致SecurityException。
SocketException
- 如果套接字无法打开,或套接字无法绑定到指定的本地端口。
SecurityException
- 如果安全管理器存在,并且其
checkListen
方法不允许操作。
SecurityManager.checkListen(int)
protected DatagramSocket(DatagramSocketImpl impl)
impl
- 子类希望在DatagramSocket上使用的
DatagramSocketImpl的一个实例。
public DatagramSocket(SocketAddress bindaddr) throws SocketException
如果地址为null
,则创建未绑定的套接字。
如果有一个安全管理器,则首先调用其checkListen
方法,使用从套接字地址的端口作为其参数,以确保允许操作。 这可能会导致SecurityException。
bindaddr
- 绑定的本地套接字地址,或未绑定套接字的
null
。
SocketException
- 如果套接字无法打开,或套接字无法绑定到指定的本地端口。
SecurityException
- 如果安全管理器存在,并且其
checkListen
方法不允许操作。
SecurityManager.checkListen(int)
public DatagramSocket(int port) throws SocketException
wildcard
地址,一个由内核选择的IP地址。
如果有安全管理器, checkListen
方法首先被调用与port
作为其参数,以确保允许该操作。 这可能会导致SecurityException。
port
- 要使用的端口。
SocketException
- 如果套接字无法打开,或套接字无法绑定到指定的本地端口。
SecurityException
- 如果安全管理器存在,并且其
checkListen
方法不允许操作。
SecurityManager.checkListen(int)
public DatagramSocket(int port, InetAddress laddr) throws SocketException
wildcard
地址。
如果有一个安全管理器,它的checkListen
方法首先被调用,以port
参数作为参数,以确保操作是允许的。 这可能会导致SecurityException。
port
- 要使用的本地端口
laddr
- 要绑定的本地地址
SocketException
- 如果套接字无法打开,或套接字无法绑定到指定的本地端口。
SecurityException
- 如果安全管理器存在,并且其
checkListen
方法不允许操作。
SecurityManager.checkListen(int)
public void bind(SocketAddress addr) throws SocketException
如果地址为null
,则系统将接收临时端口和有效的本地地址来绑定套接字。
addr
- 绑定到的地址和端口。
SocketException
- 如果在绑定期间发生任何错误,或者套接字已经绑定。
SecurityException
- 如果安全管理器存在,并且其
checkListen
方法不允许操作。
IllegalArgumentException
- 如果addr是此套接字不支持的SocketAddress子类。
public void connect(InetAddress address, int port)
如果连接到套接字的远程目的地不存在,否则无法访问,并且如果已经收到该地址的ICMP目的地不可达分组,则后续的发送或接收调用可能会引发PortUnreachableException。 注意,不能保证会抛出异常。
如果已经安装了安全管理器,则调用它来检查对远程地址的访问。 具体来说,如果给定的address
是multicast address
,那么安全管理器的checkMulticast
方法将使用给定的address
进行调用。 否则,将使用给定的address
和port
来调用安全管理器的checkConnect
和checkAccept
方法来验证是否允许数据报被发送和接收。
当连接套接字时, receive
和send
将不会对传入和传出数据包执行任何安全检查 ,而不是匹配数据包和套接字的地址和端口。 在发送操作中,如果数据包的地址被设置,并且数据包的地址和套接字的地址不匹配,则会抛出一个IllegalArgumentException
。 连接到组播地址的套接字只能用于发送数据包。
address
- 套接字的远程地址
port
- 套接字的远程端口。
IllegalArgumentException
- 如果地址为空,或者端口超出范围。
SecurityException
- 如果已安装安全管理器,并且不允许访问给定的远程地址
disconnect()
public void connect(SocketAddress addr) throws SocketException
如果给定了InetSocketAddress
,此方法的行为就好像调用connect(InetAddress,int)
与给定的套接字地址的IP地址和端口号。
addr
- 远程地址。
SocketException
- 如果连接失败
IllegalArgumentException
- 如果
addr
是
null
,或
addr
是这个套接字不支持的SocketAddress子类
SecurityException
- 如果已安装安全管理器,并且不允许访问指定的远程地址
public void disconnect()
public boolean isBound()
如果套接字被绑定在closed
之前,则该方法将在套接字关闭后继续返回true
。
public boolean isConnected()
如果套接字之前连接closed
,则此方法将继续返回true
关闭套接字之后。
public InetAddress getInetAddress()
public int getPort()
public SocketAddress getRemoteSocketAddress()
null
如果是未连接。
如果套接字之前连接closed
,则此方法将继续关闭套接字后返回连接的地址。
SocketAddress
表示此套接字的远程端点,如果尚未连接,
null
null。
getInetAddress()
,
getPort()
,
connect(SocketAddress)
public SocketAddress getLocalSocketAddress()
SocketAddress
该套接字的本地端点的
null
如果它是封闭的或未绑定的,
null
。
getLocalAddress()
,
getLocalPort()
,
bind(SocketAddress)
public void send(DatagramPacket p) throws IOException
DatagramPacket
包括指示要发送的数据,其长度,远程主机的IP地址和远程主机上的端口号的信息。
如果有安全管理器,并且套接字当前未连接到远程地址,则此方法首先执行一些安全检查。 首先,如果p.getAddress().isMulticastAddress()
是真的,此方法调用安全管理器的checkMulticast
法p.getAddress()
作为它的参数。 如果该表达式的评估为false,则该方法会调用安全性管理器的p.getAddress().getHostAddress()
和p.getPort()
的checkConnect
方法。 每次调用安全管理器方法都可能导致SecurityException,如果不允许该操作。
p
- 要发送的
DatagramPacket
。
IOException
- 如果发生I / O错误。
SecurityException
- 如果存在安全管理员,并且其
checkMulticast
或
checkConnect
方法不允许发送。
PortUnreachableException
- 如果套接字连接到当前不可达的目的地,则可能会抛出。
注意,不能保证会抛出异常。
IllegalBlockingModeException
- 如果此套接字具有关联的通道,并且通道处于非阻塞模式。
IllegalArgumentException
- 如果套接字连接,并且连接的地址和数据包地址不同。
DatagramPacket
, SecurityManager.checkMulticast(InetAddress)
, SecurityManager.checkConnect(java.lang.String, int)
public void receive(DatagramPacket p) throws IOException
DatagramPacket
的缓冲区将填充接收到的数据。
数据包数据包还包含发送者的IP地址和发件人机器上的端口号。
该方法阻塞,直到接收到数据报。 数据报包对象的length
字段包含接收到的消息的长度。 如果消息长于数据包的长度,消息将被截断。
如果有安全管理员,如果安全管理员的checkAccept
方法不允许,则无法接收到数据包。
p
- 放置输入数据的
DatagramPacket
。
IOException
- 如果发生I / O错误。
SocketTimeoutException
- 如果以前调用了setSoTimeout,并且超时已过期。
PortUnreachableException
- 如果套接字连接到当前不可达的目的地,则可能会抛出。
注意,不能保证会抛出异常。
IllegalBlockingModeException
- 如果此套接字具有相关联的通道,并且通道处于非阻塞模式。
DatagramPacket
, DatagramSocket
public InetAddress getLocalAddress()
如果有一个安全管理器,它的checkConnect
方法首先被调用与主机地址和-1
作为参数来查看是否允许操作。
null
如果套接字被关闭,或
InetAddress
表示
wildcard
个地址如果任一插座不结合,或安全管理器
checkConnect
方法不允许该操作
SecurityManager.checkConnect(java.lang.String, int)
public int getLocalPort()
-1
如果套接字被关闭,或
0
如果没有约束。
public void setSoTimeout(int timeout) throws SocketException
> 0
。
超时为零被解释为无限超时。
timeout
- 指定的超时(以毫秒为单位)。
SocketException
- 如果底层协议有错误,例如UDP错误。
getSoTimeout()
public int getSoTimeout() throws SocketException
SocketException
- 如果底层协议有错误,例如UDP错误。
setSoTimeout(int)
public void setSendBufferSize(int size) throws SocketException
DatagramSocket
。
网络实现使用SO_SNDBUF选项作为底层网络I / O缓冲区大小的提示。
网络实现也可以使用SO_SNDBUF设置来确定可以在此套接字上发送的数据包的最大大小。
由于SO_SNDBUF是一个提示,想要验证缓冲区大小的应用程序应该调用getSendBufferSize()
。
当发送速率高时,增加缓冲区大小可允许多个输出数据包被网络实现排队。
注意:如果使用send(DatagramPacket)
发送大于DatagramPacket
的设置的DatagramPacket,那么如果发送或丢弃数据包,则它是实现特定的。
size
- 设置发送缓冲区大小的大小。
该值必须大于0。
SocketException
- 如果底层协议有错误,例如UDP错误。
IllegalArgumentException
- 如果值为0或为负数。
getSendBufferSize()
public int getSendBufferSize() throws SocketException
DatagramSocket
的SO_SNDBUF选项的值,即平台在此
DatagramSocket
上输出使用的缓冲区大小。
DatagramSocket
的SO_SNDBUF选项的值
SocketException
- 如果底层协议有错误,例如UDP错误。
setSendBufferSize(int)
public void setReceiveBufferSize(int size) throws SocketException
DatagramSocket
。
网络实现使用SO_RCVBUF选项作为底层网络I / O缓冲区大小的提示。
网络实现也可以使用SO_RCVBUF设置来确定可以在此套接字上接收的数据包的最大大小。
因为SO_RCVBUF是一个提示,所以想要确定缓冲区设置大小的应用程序应该调用getReceiveBufferSize()
。
增加SO_RCVBUF可能允许网络实现缓冲多个数据包,当数据包到达速度比使用receive(DatagramPacket)
接收的速度快。
注意:如果可以接收到大于SO_RCVBUF的数据包,则它是实现特定的。
size
- 设置接收缓冲区大小的大小。
该值必须大于0。
SocketException
- 如果底层协议有错误,例如UDP错误。
IllegalArgumentException
- 如果值为0或为负数。
getReceiveBufferSize()
public int getReceiveBufferSize() throws SocketException
DatagramSocket
的SO_RCVBUF选项的值,即该平台在此
DatagramSocket
上输入使用的缓冲区大小。
DatagramSocket
SocketException
- 如果底层协议有错误,例如UDP错误。
setReceiveBufferSize(int)
public void setReuseAddress(boolean on) throws SocketException
对于UDP套接字,可能需要将多个套接字绑定到相同的套接字地址。 这通常是为了接收组播数据包(见MulticastSocket
)。 如果在使用bind(SocketAddress)
绑定套接字之前启用SO_REUSEADDR
套接字选项,则SO_REUSEADDR
套接字选项允许将多个套接字绑定到相同的套接字地址。
注意:所有现有平台不支持此功能,因此具体实现该选项是否被忽略。 但是,如果不支持getReuseAddress()
将永远返回false
。
当创建DatagramSocket
时,初始设置为SO_REUSEADDR
被禁用。
当行为SO_REUSEADDR
启用或禁用一个套接字绑定后(见isBound()
没有定义)。
on
- 是否启用或禁用
SocketException
- 如果出现错误,启用或禁用
SO_RESUEADDR
套接字选项,或者插座已关闭。
getReuseAddress()
,
bind(SocketAddress)
,
isBound()
,
isClosed()
public boolean getReuseAddress() throws SocketException
boolean
是否启用SO_REUSEADDR的boolean。
SocketException
- 如果底层协议有错误,例如UDP错误。
setReuseAddress(boolean)
public void setBroadcast(boolean on) throws SocketException
某些操作系统可能要求Java虚拟机启动具有实现特定权限以启用此选项或发送广播数据报。
on
- 是否开启广播。
SocketException
- 如果底层协议有错误,例如UDP错误。
getBroadcast()
public boolean getBroadcast() throws SocketException
boolean
是否启用SO_BROADCAST的boolean。
SocketException
- 如果底层协议有错误,例如UDP错误。
setBroadcast(boolean)
public void setTrafficClass(int tc) throws SocketException
tc 必须在0 <= tc <= 255
范围内,否则将抛出IllegalArgumentException。
笔记:
对于互联网协议v4,该值由integer
组成,其最低有效8位表示由套接字发送的IP数据包中的TOS八位字节的值。 RFC 1349定义了TOS值如下:
IPTOS_LOWCOST (0x02)
IPTOS_RELIABILITY (0x04)
IPTOS_THROUGHPUT (0x08)
IPTOS_LOWDELAY (0x10)
在优先级字段中设置位可能会导致SocketException表示不允许该操作。
对于Internet协议v6 tc
是将被放置到IP头的sin6_flowinfo字段中的值。
tc
- 一个
int
数值。
SocketException
- 如果在设置流量类或服务类型时出错
getTrafficClass()
public int getTrafficClass() throws SocketException
由于底层网络实现可能会忽略使用setTrafficClass(int)
的流量类别或服务类型,此方法可能会返回与先前使用此DatagramSocket上的setTrafficClass(int)
方法设置的值不同的值。
SocketException
- 如果获取流量类或服务类型值时出错。
setTrafficClass(int)
public void close()
所有当前阻塞的线程在receive(java.net.DatagramPacket)
在此套接字将抛出一个SocketException
。
如果此套接字具有关联的通道,则通道也将关闭。
close
中的
Closeable
close
在接口
AutoCloseable
public boolean isClosed()
public DatagramChannel getChannel()
DatagramChannel
对象(如果有)。
如果通道本身是通过DatagramChannel.open
方法创建的,并且只有通道本身才能使用数据报套接字。
null
public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) throws IOException
当应用程序创建新的数据报套接字时,将调用套接字实现工厂的createDatagramSocketImpl
方法来创建实际的数据报套接字实现。
将null
传递给该方法是无操作的,除非工厂已经设置。
如果有安全管理员,则该方法首先调用安全管理员的checkSetFactory
方法,以确保允许操作。 这可能会导致SecurityException。
fac
- 所需工厂。
IOException
- 如果在设置数据报套接字工厂时发生I / O错误。
SocketException
- 如果工厂已经定义。
SecurityException
- 如果存在安全管理员,并且其
checkSetFactory
方法不允许操作。
DatagramSocketImplFactory.createDatagramSocketImpl()
,
SecurityManager.checkSetFactory()