Java中实现UDP的重要的类

几个关键的类:

  • DatagramSocket
  • DatagramPacket
  • NetworkInterface

1、DatagramPacket类:数据报文

如果把DatagramSocket比作创建的港口码头,那么DatagramPacket就是发送和接收数据的集装箱。

1、接收构造函数

public DatagramPacket(byte[] buf,int length) //接收数据

比如,要接收数据长度为1024的字节,构建字节缓存区byte buf[] = new byte[1024],创建DatagramPacket只需传入buf[]和长度,实现接收长度为length的包。

while (true) {     
byte buf[] = new byte[1024];     
// 接收数据     
DatagramPacket packet = new DatagramPacket(buf, buf.length);     datagramSocket.receive(packet);     
String content = new String(packet.getData()).trim();     
// ……
 }

2、发送构造函数

public DatagramPacket(byte[] buf,int length,InetAddress address,int port)

比如,要发送数据为byte[] data,构造函数需要字节数组,数组长度,接收端地址(IP)和端口(Port),构造数据报文包用来把长度为length 的包传送到指定宿主的指定的端口号。

byte[] data = paramVarArgs[0].getBytes(); DatagramPacket dataPacket = new DatagramPacket(data,         
data.length, inetAddress, BROADCAST_PORT);
try {     
datagramSocket.send(dataPacket);
} catch (IOException e) {     
e.printStackTrace();     
return App.getInstance().getResources().getString(R.string.send_failed); }
 return App.getInstance().getResources().getString(R.string.send_success);

3、主要方法

  • getAddress()返回接收或发送此数据报文的机器的 IP 地址。
  • getData()返回接收的数据或发送出的数据。
  • getLength()返回发送出的或接收到的数据的长度。
  • getPort()返回接收或发送该数据报文的远程主机端口号。

2、DatagramSocket类:数据报套接字

此类表示用来发送和接收数据报包的套接字。数据报套接字是包投递服务的发送或接收点。

1、不绑定地址及端口构造函数:DatagramSocket()创建数据报套接字。

try {     
datagramSocket = new DatagramSocket();     
datagramSocket.setBroadcast(true); } 
catch (Exception e) {     
e.printStackTrace()
; }

用于发送报文的套接字,一般不指定特定端口及地址。

2、绑定端口构造函数:DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。

3、绑定地址与端口构造函数:DatagramSocket(int port, InetAddress laddr)创建数据报套接字,将其绑定到指定的本地地址。

// 保持一个套接字打开,监听该端口上所有UDP流量(0.0.0.0表示所有未处理的流量) datagramSocket = new DatagramSocket(BROADCAST_PORT, InetAddress.getByName("0.0.0.0")); datagramSocket.setBroadcast(true);

关于0.0.0.0的意义,可参考:全零网络IP地址0.0.0.0表示意义详谈(http://www.cnblogs.com/hnrainll/archive/2011/10/13/2210101.html)

4、主要方法

  • receive(DatagramPacket p)从此套接字接收数据报包。
  • void send(DatagramPacket p)从此套接字发送数据报包。
  • bind(SocketAddress addr)将此 DatagramSocket 绑定到特定的地址和端口。
  • void close()关闭此数据报套接字。
  • void connect(InetAddress address, int port)将套接字连接到此套接字的远程地址。
  • void connect(SocketAddress addr)将此套接字连接到远程套接字地址(IP 地址 + 端口号)。
  • void disconnect()断开套接字的连接。
  • getInetAddress()返回此套接字连接的地址。
  • InetAddress getLocalAddress()获取套接字绑定的本地地址。

3、NetworkInterface类:网络接口

NetworkInterface是JDK1.4中添加的一个获取网络接口的类,该网络接口既可以是物理的网络接口,也可以是虚拟的网络接口,而一个网络接口通常由一个 IP 地址来表示。

既然 NetworkInterface 用来表示一个网络接口,那么如果可以获得当前机器所有的网络接口(包括物理的和虚拟的),然后筛选出表示局域网的那个网络接口,那就可以得到机器在局域网内的 IP 地址。

NetworkInterface常用到的方法有两个:

  • getNetworkInterfaces()用于获取当前机器上所有的网络接口;
  • getInetAddresses()用于获取绑定到该网卡的所有的 IP 地址。

来看下这段代码,实现的功能是遍历所有本地网络接口,获取广播地址,并向它们发送广播报文。

// 获取本地所有网络接口
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {     
NetworkInterface networkInterface = interfaces.nextElement();     
if (networkInterface.isLoopback() || !networkInterface.isUp()) {         
continue;    
 }     
// getInterfaceAddresses()方法返回绑定到该网络接口的所有 IP 的集合     
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {         InetAddress broadcast = interfaceAddress.getBroadcast();         /
/ 不广播回环网络接口         
if (broadcast  == null) {             
continue;        
 }         
// 发送广播报文         
try {             
DatagramPacket sendPacket = new DatagramPacket(data,                     
data.length, broadcast, BROADCAST_PORT);             
datagramSocket.send(sendPacket);         
} catch (Exception e) {             
e.printStackTrace();        
 }         
Log.d("发送请求", getClass().getName() + ">>> Request packet sent to: " +                 broadcast.getHostAddress() + "; Interface: " + networkInterface.getDisplayName());    
 }
}

getInterfaceAddresses方法返回的是一个绑定到该网络接口的所有 InterfaceAddress 的集合。InterfaceAddress 是 JDK1.6 之后添加的类,包含 IP 地址(InetAddress),以及该地址对应的广播地址和掩码长度。

以上内容部分出自使用 NetworkInterface 获得本机在局域网内的 IP 地址。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值