UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。
UDP和TCP协议的区别:
1、连接方面区别
TCP面向对象连接(如打电话要先拨号建立连接)。
UDP是无连接的,即发送数据之前不需要建立连接。
2、安全方面的区别
TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达。
UDP尽最大努力交付,即不保证可靠交付。安全系数低。
3、传输效率的区别
TCP传输效率相对较低。
UDP传输效率高,适用于对高速传输和实时性有较高的通信或广播通信。
4、连接对象数量的区别
TCP连接只能是点到点、一对一的。
UDP支持一对一,一对多,多对一和多对多的交互通信。
UDP的实现过程:
发送方:
(1)DatagramSocket创建数据包套接字,并将其绑定到指定的端口;
(2)使用DatagramPacket创建要发送的数据包,数据包一般包括四部分内容:自己ip,port、对方的ip,port、字节数组、字节数组长度;
(3)DatagramSocket类的send方法发送数据包。
package edu.udp.client;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UdpClient {
public static void main(String[] args) throws Exception {
DatagramSocket poster = null;
poster = new DatagramSocket(); //准备邮局
String mesg = "你好!";
// int a =10;
//准备邮包
DatagramPacket packet = new DatagramPacket(mesg.getBytes(),mesg.getBytes().length,
InetAddress.getByName("127.0.0.1"),/*网络连接信息*/
9999);
//邮局发邮报
poster.send(packet);
// DatagramSocket poster1 = new DatagramSocket(9123);
// //创建好缓存包
// DatagramPacket packet1 = new DatagramPacket(new byte[1024],1024); //
// System.out.println("等待接受数据包");
// //接收
// poster1.receive(packet); //接收 == 复制 复制发送过来的数据 并覆盖
//
// byte[] temp = packet1.getData(); //取出数据
// int length = packet1.getLength(); //取出有效长度 不是初始化长度
// String str = new String(temp,0,length); //起始索引 --- 有效长度
//
// System.out.println(str);
}
}
发送一个学生类对象:
package edu.udp.client;
import edu.Student;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UdpObjectClient {
public static void main(String[] args) throws Exception {
DatagramSocket poster = null;
poster = new DatagramSocket(); //准备邮局
int a = 200;
double b = 124.35;
Student s = new Student(12423,"kaka",'男');
//把数据转换为字节数组 法一:写到文件里再读出来(文件里) 法二:字节数组流(终端设备为内存 )
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream objout = new ObjectOutputStream(bos);
objout.writeInt(a);
objout.writeDouble(b);
objout.writeObject(s);
objout.flush();
byte[] t = bos.toByteArray(); //得到数据
objout.close();
DatagramPacket packet = new DatagramPacket(t,t.length,
InetAddress.getByName("127.0.0.1")
,9999);
poster.send(packet);
}
}
接收方:
(1)DatagramSocket创建数据包套接字,并将其绑定到指定的端口;
(2)使用DatagramPacket创建字节数组来接受数据包,数据包一般包括四部分内容:自己ip,port、对方的ip,port、字节数组、字节数组长度;
(3)DatagramSocket类的receive方法接受数据包。
package edu.udp.sever;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UdpSever {
public static void main(String[] args) throws Exception {
DatagramSocket poster = new DatagramSocket(9999);
//创建好缓存包
DatagramPacket packet = new DatagramPacket(new byte[1024],1024); //
System.out.println("等待接受数据包");
//接收
poster.receive(packet); //接收 == 复制 复制发送过来的数据 并覆盖
byte[] temp = packet.getData(); //取出数据
int length = packet.getLength(); //取出有效长度 不是初始化长度
String str = new String(temp,0,length); //起始索引 --- 有效长度
// System.out.println(temp);
// System.out.println(length);
System.out.println(str);
// String ip = packet.getAddress().getHostAddress();
// int port = packet.getPort();
//
// String str1 = "hello!";
// byte[] a = str1.getBytes();
// DatagramPacket p = new DatagramPacket(a,a.length,
// InetAddress.getByName(ip) /*packet.getAddress*/
// ,port);
// poster.send(p);
}
}
接收一个学生类对象:
package edu.udp.sever;
import edu.Student;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UpdObjectSever {
public static void main(String[] args) throws Exception {
DatagramSocket poster = new DatagramSocket(9999);
//创建好缓存包
DatagramPacket packet = new DatagramPacket(new byte[1024],1024); //
System.out.println("等待接受数据包");
//接收
poster.receive(packet); //接收 == 复制
byte[] data = packet.getData();
//字节数组输入流
ByteArrayInputStream bis = new ByteArrayInputStream(data);
ObjectInputStream objin = new ObjectInputStream(bis);
int a = objin.readInt();
double b = objin.readDouble();
Student s = (Student) objin.readObject();
System.out.println(a +":"+ b + ":" + s);
}
}
DatagramPacket常使用的方 法:
运行结果:
String str = new String(temp,0,length),字节数组的有效长度。