- 韩慧腾
一、UDP通信
UDP协议的特点
- UDP是一种无连接、不可靠传输协议
- 将数据源IP、目的地IP和端口以及数据封装成数据包,大小限制在64KB之内,直接发送出去即可
DatagramPacket类(java.net包下):数据包对象
DatagramSocket类(java.net包下):发送端和接收端(人)
代码模拟UDP通信:
package com.itheima;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author hanhan
* date 2022/4/27 11:01
* 努力已经来不及了,你得拼命
* 接收端
*/
public class ServerDemo_00 {
public static void main(String[] args) throws Exception {
System.out.println("接收端启动");
//创建接收端对象,注册端口
DatagramSocket d = new DatagramSocket(8888);
//创建数据包对象
byte[] buffer=new byte[1024*64];
DatagramPacket dd = new DatagramPacket(buffer,buffer.length);
//等待接收数据
d.receive(dd);
int len=dd.getLength();
String s=new String(buffer,0,len);
System.out.println("接收的数据"+s);
//获取发送端的IP地址
System.out.println("对方的IP地址:"+dd.getSocketAddress());
//获取发送端的端口
System.out.println("对方的端口:"+dd.getPort());
d.close();
}
}
package com.itheima;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author hanhan
* date 2022/4/27 10:59
* 努力已经来不及了,你得拼命
* 发送端/客户端
*/
public class ClientDemo_00 {
public static void main(String[] args) throws Exception {
System.out.println("发送端启动");
//创建一个发送端对象,,发送端自带默认端口号
DatagramSocket d = new DatagramSocket(6666);//参数可以指定发送端的端口
//创建一个数据包对象封装数据
byte[] buffer="智者不如爱河,建设美丽中国".getBytes();
DatagramPacket dd = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888);
//发送数据
d.send(dd);
//System.out.println(InetAddress.getLocalHost());
d.close();
}
}
提醒:先运行接收端,再运行发送端
多发多收:
package com.itheima;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
* @author hanhan
* date 2022/4/28 23:00
* 努力已经来不及了,你得拼命
* 发送端(实现多发多收)
*/
public class ClientDemo_01 {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//创建一个发送端对象,,发送端自带默认端口号
DatagramSocket d = new DatagramSocket(6666);//参数可以指定发送端的端口
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入弹幕:");
String s=sc.nextLine();
if("exit".equals(s)){
System.out.println("退出");
break;
}
//创建一个数据包对象封装数据
byte[] buffer=s.getBytes();
DatagramPacket dd = new DatagramPacket(buffer, buffer.length, InetAddress.getLocalHost(), 8888);
//发送数据
d.send(dd);
}
}
}
package com.itheima;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author hanhan
* date 2022/4/28 23:01
* 努力已经来不及了,你得拼命
* 接收端(实现多发多收)
*/
public class ServerDemo_01 {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动");
//创建接收端对象,注册端口
DatagramSocket d = new DatagramSocket(8888);
//创建数据包对象
byte[] buffer=new byte[1024*64];
DatagramPacket dd = new DatagramPacket(buffer,buffer.length);
while (true) {
//等待接收数据
d.receive(dd);
int len=dd.getLength();
String s=new String(buffer,0,len);
System.out.println("接收的数据"+s);
//获取发送端的IP地址
System.out.println("对方的IP地址:"+dd.getSocketAddress());
//获取发送端的端口
System.out.println("对方的端口:"+dd.getPort());
}
}
}
二、UDP三种通信方式
- 单播:单台主机与单台主机之间的通信
- 广播:当前主机与网络中的所有主机通信
- 组播:当前主机与选定的一组主句的通信
UDP如何实现广播?
- 使用广播地址:255.255.255.255
- 具体操作:
1)发送端发送的数据包的目的地写的是广播地址,且指定端口。(255.255.255.255 , 9999)
2)本机所在网段的其他主机的程序只要匹配端口成功就可以收到消息了
package com.itheima;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author hanhan
* date 2022/4/27 10:59
* 努力已经来不及了,你得拼命
* 发送端/客户端
*/
public class ClientDemo_00 {
public static void main(String[] args) throws Exception {
System.out.println("发送端启动");
//创建一个发送端对象,,发送端自带默认端口号
DatagramSocket d = new DatagramSocket(6667);//参数可以指定发送端的端口
//创建一个数据包对象封装数据
byte[] buffer="智者不如爱河,建设美丽aa".getBytes();
DatagramPacket dd = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), 9990);
//发送数据
d.send(dd);
//System.out.println(InetAddress.getLocalHost());
d.close();
}
}
package com.itheima;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author hanhan
* date 2022/4/27 11:01
* 努力已经来不及了,你得拼命
* 接收端
*/
public class ServerDemo_00 {
public static void main(String[] args) throws Exception {
System.out.println("接收端启动");
//创建接收端对象,注册端口
DatagramSocket d = new DatagramSocket(9990);
//创建数据包对象
byte[] buffer=new byte[1024*64];
DatagramPacket dd = new DatagramPacket(buffer,buffer.length);
//等待接收数据
d.receive(dd);
int len=dd.getLength();
String s=new String(buffer,0,len);
System.out.println("接收的数据"+s);
//获取发送端的IP地址
System.out.println("对方的IP地址:"+dd.getSocketAddress());
//获取发送端的端口
System.out.println("对方的端口:"+dd.getPort());
d.close();
}
}
UDP如何实现组播?
- 使用组播地址:224.0.0.0~239.255.255.255
- 具体操作:
1)发送端的数据包的目的地是组播IP(eg:224.0.1.1,9999)
2)接收端必须绑定该组播IP(224.0.1.1),端口还要对应发送端的目的端口9999,这样即可接收该组播消息
3)DatagramSocket的子类MulticastSocket可以在接收端绑定组播IP
package com.itheima;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* @author hanhan
* date 2022/4/28 23:01
* 努力已经来不及了,你得拼命
* 组播接收端
*/
public class ServerDemo_01 {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动");
//创建接收端对象,注册端口
MulticastSocket d = new MulticastSocket(8888);
d.joinGroup(InetAddress.getByName("224.0.1.1"));
//创建数据包对象
byte[] buffer=new byte[1024*64];
DatagramPacket dd = new DatagramPacket(buffer,buffer.length);
while (true) {
//等待接收数据
d.receive(dd);
int len=dd.getLength();
String s=new String(buffer,0,len);
System.out.println("接收的数据"+s);
//获取发送端的IP地址
System.out.println("对方的IP地址:"+dd.getSocketAddress());
//获取发送端的端口
System.out.println("对方的端口:"+dd.getPort());
}
}
}
package com.itheima;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
* @author hanhan
* date 2022/4/28 23:00
* 努力已经来不及了,你得拼命
* 组播发送端
*/
public class ClientDemo_01 {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//创建一个发送端对象,,发送端自带默认端口号
DatagramSocket d = new DatagramSocket(6666);//参数可以指定发送端的端口
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入弹幕:");
String s=sc.nextLine();
if("exit".equals(s)){
System.out.println("退出");
break;
}
//创建一个数据包对象封装数据
byte[] buffer=s.getBytes();
DatagramPacket dd = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("224.0.1.1"), 8888);
//发送数据
d.send(dd);
}
}
}