一、UDP定义
OSI七层网络模型
应用层(HTTP、FTP、SMTP、POP3、TELNET)
表示层
会话层
传输层(TCP、UDP)
网络层(IP)
数据链路层
物理层
其中UDP协议是属于传输层的协议,它是面向无连接的协议。在数据传输时,数据的发送端和接收端不建立逻辑联系。换句话说,一台计算机向另一台计算机发送数据时,发送端不会确定接收端是否存在,就会发出数据。
二、UDP特点
- UDP协议传输效率高,不安全,容易丢包。
- 类似于发短信,发送前不关心对方是否能够接收。接收后也不会给发送者一个反馈。一般用于对数据完整性要求不高的场景:视频聊天,直播,游戏。
- UDP在传输时会将数据进行分包处理,每一个包的大小不能超过64k.
三、InetAddress对象与InetSocketAddress的使用
【InnetAddres】常用方法
- 获取主机名称 getHostName()
- 获取主机IP地址 getHostAddress()
- 获取本地IP信息 getLocalHost()
- 创建InetAddress对象 getByName()
方法演示
public static void main(String[] args) throws UnknownHostException {
//传入主机名,获取InetAddress对象
InetAddress ia = InetAddress.getByName("www.baidu.com");
//获取主机名称
System.out.println(ia.getHostName());
//获取主机IP地址
System.out.println(ia.getHostAddress());
//获取本地IP信息
System.out.println(InetAddress.getLocalHost());
}
结果:
www.baidu.com
180.101.49.12
DESKTOP-4DVNG1L/192.168.145.1
【InneSocketAddress】常用方法
- 获取主机名 getHostName()
- 获取端口号 getPort()
public static void main(String[] args) throws UnknownHostException {
//创建InetSocketAddress对象,并且传入主机名与端口号
InetSocketAddress isa = new InetSocketAddress("www.baidu.com", 80);
//获取主机名
System.out.println(isa.getHostName());
//获取端口号
System.out.println(isa.getPort());
}
结果:
www.baidu.com
80
四、UDP练习(聊天)
【发送】
public class User1 implements Runnable{
//创建DatagramSocket对象,用于传送DatagramPacket对象
private DatagramSocket ds;
//创建DatagramPacket对象,用于转载内容
private DatagramPacket dp;
private Scanner scan;
@Override
public void run() {
try {
ds = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
//new Scanner(System.in)具有阻塞作用,该行没有执行,后面的内容便不会执行
scan = new Scanner(System.in);
while(true){
String content = scan.nextLine();
try {
//创建DatagramPacket对象用于装载内容
//传入内容字节流,内容长度,InetAddress对象(主要用于获取对面主机名)以及端口号
dp = new DatagramPacket(content.getBytes(), content.getBytes().length,
InetAddress.getByName("localhost"), 12306);
//转载信息
ds.send(dp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
设置发送主机为localhost(本地地址,可以修改为同一局域网内的IP地址)
设置端口号为12306
【接收】
public class User2 implements Runnable{
private DatagramSocket ds;
private DatagramPacket dp;
@Override
public void run() {
try {
//设置端口号,接收传递过来的内容
ds = new DatagramSocket(12306);
} catch (SocketException e) {
e.printStackTrace();
}
//设置字节缓冲区
byte[] b = new byte[1024];
//实例化DatagramPacket对象
dp = new DatagramPacket(b, b.length);
while(true){
try {
//接收传递过来的内容
ds.receive(dp);
//dp.getAddress()获取IP地址
//dp.getData()获取发送内容
System.out.println(dp.getAddress()+":"+new String(dp.getData(), 0, dp.getLength()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
接收12306端口发来的内容
同样通过DatagramSocket 与 DatagramPacket接收内容
【测试】
public static void main(String[] args) {
new Thread(new User1()).start();
new Thread(new User2()).start();
}