网络编程之UDP

时间:2022-12-18 00:00:28

UDP协议

UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。

由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。

但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。

 

 DatagramPacket 类:UDP通信中发送或者接收的数据。

 

创建DatagramPacket对象时,不仅指定了封装数据的字节数组和数据的大小,还指定了数据包的目标IP地址(addr)和端口号(port)。该对象通常用于发送端,因为在发送数据时必须指定接收端的IP地址和端口号,就好像发送货物的集装箱上面必须标明接收人的地址一样。

 DatagramSocket 类: 作用就类似于码头,使用这个类的实例对象就可以发送和接收DatagramPacket数据包

 

InetAddress 类:封装一个IP地址,并提供了一系列与IP地址相关的方法,主要有getLocalhost()返回本地主机IP地址的封装对象;   getByName(String IP)根据字符串ip地址或者域名得到ip地址的封装对象InetAddress; getHostName()根据InetAddress对象获取此IP对象的主机名;  getHostAddress()根据InetAddress对象获取此IP对象的IP地址,返回IP地址的字符串;

 

 

要实现UDP通信需要创建一个发送端程序和一个接收端程序,很明显,在通信时只有接收端程序先运行,才能避免因发送端发送的数据无法接收,而造成数据丢失。因此,首先需要来完成接收端程序的编写。

 

 1 import java.io.IOException;
 2 import java.net.DatagramPacket;
 3 import java.net.DatagramSocket;
 4 import java.net.InetAddress;
 5 /**
 6   *  UTP数据发送端
 7   *   
 8   */    
 9 public class Send {
10     public static void main(String[] args) throws IOException {
11         //1.创建数据报包套接字DatagramSocket对象
12         DatagramSocket socket = new DatagramSocket();
13         /*    数据报包需要接收数据,先准备数据
14          * DatagramPacket(byte[] bytes,int length,InetAddress ip,int port);
15          */
16         //2.设置参数
17         byte[] bytes="hello,word".getBytes();
18         int length = bytes.length;
19         //通过IP地址字符串,获取IP封装对象
20         InetAddress ip = InetAddress.getByName("127.0.0.1");
21         int porn = 6666;
22         //3.创建数据报包DatagramPacket对象,并封装数据
23         DatagramPacket dp =new DatagramPacket(bytes,length,ip,porn);
24         //4.套接字发送数据报包
25         socket.send(dp);
26         //5.释放资源
27         socket.close();
28     }
29 }
30  

 

 1 package udpdemo;
 2 
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.InetAddress;
 7 /**
 8  * 
 9  * UDP接收端
10  *    
11  */
12 
13 
14 public class Receive {
15     public static void main(String[] args) throws IOException {
16         //设置接受数据的端口
17         int porn = 8888;
18         //创建接收端的DatagramSocket对象
19         DatagramSocket socket = new DatagramSocket(porn);
20         //创建接受数据的字节数组
21         byte [] receive = new byte[1024];
22         //限制接受数据的长度
23         int length = 1024;
24         //创建接受端的数据报包对象
25         DatagramPacket dp = new DatagramPacket(receive,length);
26         //接收数据存储到数据报包dp中
27         socket.receive(dp);
28         /**
29          * 拆包获取数据
30          * geAddress()根据数据报包获取发送端的ip地址对象
31          * getHostAddress() 根据ip地址对象获取IP地址
32          * getHostName() 根据IP地址对象获取此IP的主机名
33          * 
34          * getData()根据数据报包获取数据,返回值byte[]类型
35          * getLength()根据数据报包获取实际接受数据的数量
36          * 
37          * 
38          */
39         //根据数据报包获取发送端的ip地址对象
40         InetAddress ipObject = dp.getAddress();
41 //        根据ip地址对象获取IP地址
42         String ip=ipObject.getHostAddress();
43         //根据IP地址对象获取此IP的主机名
44         String hostName=ipObject.getHostName();
45         //获取端口
46         int receiveporn=dp.getPort();
47         //获取接受数据的长度
48         int str=dp.getLength();
49         //获取数据包接受的数据
50         byte[] receiveb=dp.getData();
51                 
52         
53                 
54 //        打印数据
55         System.out.println("发送端IP地址对象:"+ipObject);    
56         System.out.println("发送端IP地址"+ip);
57         System.out.println("获取发送端主机名"+hostName);
58         System.out.println("获取发送端数据报包数据"+new String(receiveb,0,str));
59         System.out.println("获取发送端端口:"+receiveporn);
60         System.out.println("获取数据长度:"+str);
61         socket.close();
62         
63     }
64     /**输出
65      *  发送端IP地址对象:www.fu.com/127.0.0.1
66         发送端IP地址127.0.0.1
67         获取发送端主机名www.fu.com
68         获取发送端数据报包数据hello,word
69         获取发送端端口:59399
70         获取数据长度:10    
71      * 
72      * 
73      */
74     
75 }