UDP协议的简介
UDP协议是一种面向无连接不可靠的协议,也就是在进行数据通讯之前发送端和接收端无需进行连接,发送端要发送数据,
只需构造数据报,并将接收端的地址放入数据报中,然后将其发送出去就可以了.
该协议是一种不可靠的协议,因为收发放没有连接过程, 发送出去的数据有可能中途丢失,并且发送端还得不到反馈.
所以在实现UDP协议的程序中,最关键是如何实现UDP的数据报.
JAVA中提供了实现UDP协议的两个关键类
数据报类:DatagramPacket:构建一个数据报,里面可以放入要发送的数据以及接收端的地址.
UDP端类:DatagramSocket:构建实行UDP功能的发送端与接收端,实现发送与接收数据报
DatagramPacket:
DatagramSocket:
UDP协议网络编程方法
接收端程序编写:
①调用DatagramSocket(int port)创建一个数据报套接字,并绑定到指定端口上;
②调用DatagramPacket(byte[] buf, int length),建立一个字节数组以接收UDP包 。
③调用DatagramSocket类的receive(),接收UDP包。
④最后关闭数据报套接字。
发送端程序编写:
①调用DatagramSocket()创建一个数据报套接字;
②调用DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port),建立要发送的UDP包。
③调用DatagramSocket类的send(),发送UDP包。
④最后关闭数据报套接字。
一方发,一方收:
发送方:
public class DataPacketSend
{
public static void main(String[] args) throws Exception
{
// DatagramPacket dp1=null;
// DatagramSocket ds=null;
String str=null;
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
str=keyin.readLine();
DatagramPacket dp1=new DatagramPacket(str.getBytes(),0,str.getBytes().length,
InetAddress.getByName("127.0.0.1"),6000);
DatagramSocket ds=new DatagramSocket();
ds.send(dp1);
ds.close();
}
}
接收方:
public class DataPacketReceive
{
public static void main(String[] args) throws Exception
{
DatagramPacket dp1=null;
DatagramSocket ds=null;
byte[] buf=new byte[1024];
int len=0;
dp1=new DatagramPacket(buf,0,buf.length);
ds=new DatagramSocket(6000);
ds.receive(dp1);
len=dp1.getLength();
System.out.println(new String(buf,0,len));
ds.close();
}
}
发送并接收:
public class DataPacketSend2 {
public static void main(String[] args)throws Exception{
DatagramSocket ds=new DatagramSocket();
byte[] sbuf=new byte[1024];
byte[] rbuf=new byte[1024];
DatagramPacket sdp=new DatagramPacket(sbuf,sbuf.length);
DatagramPacket rdp=new DatagramPacket(rbuf,rbuf.length);
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
String str=null;
InetAddress IP=InetAddress.getByName("127.0.0.1");
while(true){
System.out.print("请输入要发送的消息:");
str=keyin.readLine();
sbuf=str.getBytes();
sdp.setAddress(IP);
sdp.setPort(12345);
sdp.setData(sbuf,0,str.length());
ds.send(sdp);
if(str.trim().equals("bye"))
break;
System.out.println("等待对方回复.....");
ds.receive(rdp);
rbuf=rdp.getData();
str=new String(rbuf,0,rdp.getLength());
System.out.println("对方回复: "+str);
if(str.trim().equals("bye"))
break;
}
ds.close();
keyin.close();
}
}
public class DataPacketReceive2 {
public static void main(String[] args)throws Exception{
DatagramSocket ds=new DatagramSocket(12345);
byte[] sbuf=new byte[1024];
byte[] rbuf=new byte[1024];
DatagramPacket sdp=new DatagramPacket(sbuf,sbuf.length);
DatagramPacket rdp=new DatagramPacket(rbuf,rbuf.length);
BufferedReader keyin=new BufferedReader(new InputStreamReader(System.in));
String str=null;
while(true){
System.out.println("等待对方消息.....");
ds.receive(rdp);
rbuf=rdp.getData();
str=new String(rbuf,0,rdp.getLength());
System.out.println(str);
if(str.trim().equals("bye"))
break;
System.out.print("请输入消息: ");
str=keyin.readLine();
sbuf=str.getBytes();
sdp.setAddress(rdp.getAddress());
sdp.setPort(rdp.getPort());
sdp.setData(sbuf);
sdp.setLength(str.length());
ds.send(sdp);
if(str.trim().equals("bye"))
break;
}
ds.close();
keyin.close();
}
}
UDP广播:
MulticastSocket类
多播数据报套接字类用于发送和接收 IP 多播包。MulticastSocket 是一种 (UDP) DatagramSocket,它具有加入
Internet上其他多播主机的“组”的附加功能。
多播组通过 D 类 IP 地址和标准 UDP 端口号指定。D 类 IP 地址在 224.0.0.0 和 239.255.255.255 的范围内(包括两
者)。地址 224.0.0.0 被保留,不应使用。
组播和广播的区别?
如同上个例子,当有多台主机想要接收相同的报文,广播采用的方式是把报文传送到局域网内每个主机上,不管这个主机是否对报文感兴趣。这样做就会造成了带宽的浪费和主机的资源浪费。而组播有一套对组员和组之间关系维护的机制,可以明确的知道在某个子网中,是否有主机对这类组播报文感兴趣,如果没有就不会把报文进行转发,并会通知上游路由器不要再转发这类报文到下游路由器上。
发送接收数据报的方法与DatagramSocket完全一样.MulticastSocket比DatagramSocket多了一个setTimeToLive(int ttl)方法:该ttl参数用于设置数据报最多可以跨过多少个网络:
ttl = 0:数据报停留在本地主机
ttl = 1:数据报发送到本地局域网(默认)
ttl = 32:只能发送到本站点的网络上
ttl = 64:数据报应保留在本地区
ttl = 128:数据报应保留在本大洲
ttl = 255:数据报可以发送到所有地方
public class muitSend {
public static void main(String[] args)throws Exception{
MulticastSocket ms=new MulticastSocket();
InetAddress mulIp=InetAddress.getByName("224.0.0.1");
int port=6000;
ms.joinGroup(mulIp);
byte[] sbuf=new byte[1024];
while(true){
int len=System.in.read(sbuf,0,sbuf.length);
if(len>0){
DatagramPacket sdp=new DatagramPacket(sbuf,len,mulIp,port);
ms.send(sdp);
}
else
break;
}
}
}
示例基于UDP的MulticastSocket编程(接收):
public class muitReceive {
public static void main(String[] args)throws Exception{
MulticastSocket ms=new MulticastSocket(6000);
InetAddress mulIp=InetAddress.getByName("224.0.0.1");
ms.joinGroup(mulIp);
byte[] rbuf=new byte[1024];
while(true){
DatagramPacket rdp=new DatagramPacket(rbuf,rbuf.length);
ms.receive(rdp);
if(rdp.getLength()>0)
System.out.write(rbuf,0,rdp.getLength());
else
break;
}
}
}