================================================
TCP和UDP的分界线
=================================================
(2)UDP协议:(速度快,无连接,不可靠)
不需要建立连接(因为把数据源IP、目的地IP、端口封装成数据包),每个数据包在64KB内,只管发,不管对方有没有接到确认什么的。
优点:可以广播发送,发送数据结束时无需释放资源,开销小,速度快。
使用场景:语言通话、视频通话等。
ps:这个就是一股脑的什么都封装一起,直接往外抛就什么都不管了,当然快了。
例子:
一收一发
发送端(客户端)
package bao; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class Test { public static void main(String[] args) throws Exception { //一、发送端(测试时候先启动接收再发送端) //1.创建发送端对象,发送端自带默认端口号(人) System.out.println("========客户端启动============"); DatagramSocket socket1 = new DatagramSocket();//不定义就默认端口 //2.创建一个要发送的数据容器(容器里面有数据) byte[] a ="我是水".getBytes(); //3.创建一个数据包对象把容器装起来 DatagramPacket packet1 = new DatagramPacket(a,a.length, InetAddress.getLocalHost(),8899);//数据,大小,服务端的IP,服务端的端口 //4.发送出去 socket1.send(packet1); //5.关闭资源,避免资源浪费 socket1.close(); } }
接收端 (服务端)
package bao; import java.net.DatagramPacket; import java.net.DatagramSocket; public class Test1 { public static void main(String[] args) throws Exception { //二、接收端(测试时候先启动接收再发送端) //1.创建接收端对象,注册端口(人) System.out.println("=========接收端启动==============="); DatagramSocket socket2 = new DatagramSocket(8899); //2.创建一个要接收的数据容器(等待接收数据) byte[]b =new byte[1024*64]; //3.把容器数据打包 DatagramPacket packet2 = new DatagramPacket(b,b.length); //4.等待接收数据 socket2.receive(packet2); //5.读取多少倒出多少 int len = packet2.getLength(); String rs = new String(b,0,len); System.out.println("接收到了数据了"+rs); //6.关闭资源,避免资源浪费 socket2.close(); } } //额外知识点,获取对方端口和ip地址 //String ip = packet2.getAddress().toString(); //System.out.println("对方IP地址为"+ip); //int port = packet2.getPort(); //System.out.println("对方端口位置"+port);
运行结果:
========客户端启动============
=========接收端启动===============
接收到了数据了我是水
多收多发
思想:把一收一发代码拿来改进就好了
发送端:把主要发送的代码写入死循环并写一个键盘输入代码,只有用户输入exit才能退出循环。
接收端:把等待接收的封装包开始写入死循环里面,然后再把释放资源的代码注释掉才能一直接收
发送端(客户端)
package bao; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; //发送端 public class Test { public static void main(String[] args) throws Exception { //一、1.创建发送端对象,发送端自带默认端口号(人) DatagramSocket socket1 = new DatagramSocket();//不定义就默认端口 System.out.println("========客户端启动============"); //二.6创建键盘录入 Scanner sc = new Scanner(System.in); while (true) {//二、5.死循环把代码封起来(多收多发步骤) //二、6.接收键盘录入 System.out.println("请输入:"); String msg = sc.nextLine(); //二、7.设置exit退出 if ("exit".equals(msg)){ System.out.println("离线成功"); socket1.close();//释放资源 break; } //2.创建一个要发送的数据容器(容器里面有数据) byte[] a =msg.getBytes(); //3.创建一个数据包对象把容器装起来 DatagramPacket packet1 = new DatagramPacket(a,a.length, InetAddress.getLocalHost(),8899);//数据,大小,服务端的IP,服务端的端口 //4.发送出去 socket1.send(packet1); } } }
接收端 (服务端)
package bao; import java.net.DatagramPacket; import java.net.DatagramSocket; //二、接收端 public class Test1 { public static void main(String[] args) throws Exception { //1.创建接收端对象,注册端口(人) System.out.println("=========接收端启动==============="); DatagramSocket socket2 = new DatagramSocket(8899); //2.创建一个要接收的数据容器(等待接收数据) byte[]b =new byte[1024*64]; //3.把容器数据打包 DatagramPacket packet2 = new DatagramPacket(b,b.length); while (true) {//二、6.把封装代码写入死循环并删掉释放资源的代码(多收多发步骤) //4.等待接收数据 socket2.receive(packet2); //5.读取多少倒出多少 int len = packet2.getLength(); String rs = new String(b,0,len); System.out.println("接收到了来自:"+packet2.getAddress()+"对方端口是:"+packet2.getPort()+rs); } } } //额外知识点,获取对方端口和ip地址 //String ip = packet2.getAddress().toString(); //System.out.println("对方IP地址为"+ip); //int port = packet2.getPort(); //System.out.println("对方端口位置"+port);
运行结果:
========客户端启动============
请输入:
你在吗
请输入:
在干嘛
请输入:
=========接收端启动===============
接收到了来自:(隐私不展示)对方端口是:(隐私不展示)你在吗
接收到了来自:(隐私不展示)对方端口是:(隐私不展示)在干嘛
多开客户端 步骤
一台主机中可以创建很多个客户端给接收端发消息
1.在客户端的页面右上角点击
2.找到Allow multiple instances勾选完成
广播(当前主机和所在网络中的所有主机通信)
步骤:(前提在同一网段内)
发送端的参数地址指定为255.255.255.255,并且指定端口:例如6666
接收端的参数端口只要匹配成功就可以了,例如:6666
例子:
发送端
//修改前 //3.创建一个数据包对象把容器装起来 DatagramPacket packet1 = new DatagramPacket(a,a.length, InetAddress.getLocalHost(),8899);//数据,大小,服务端的IP,服务端的端口 //修改后 //3.创建一个数据包对象把容器装起来 DatagramPacket packet1 = new DatagramPacket(a,a.length, InetAddress.getByName("255.255.255.255"),6666);//数据,大小,服务端的IP,服务端的端口
接收端
//修改前 //1.创建接收端对象,注册端口(人) System.out.println("=========接收端启动==============="); DatagramSocket socket2 = new DatagramSocket(8899); //修改后 //1.创建接收端对象,注册端口(人) System.out.println("=========接收端启动==============="); DatagramSocket socket2 = new DatagramSocket(6666);
组播 (当前主机和所在网络中的一组主机通信)
发送端和接收端都要用MulticastSocket绑定同一个IP地址和绑定同一个端口
范围:224.0.0.0~~~~239.255.255.255
发送端
//修改前 //3.创建一个数据包对象把容器装起来 DatagramPacket packet1 = new DatagramPacket(a,a.length, InetAddress.getByName("255.255.255.255"),6666);//数据,大小,服务端的IP,服务端的端口 //修改后 //3.创建一个数据包对象把容器装起来 DatagramPacket packet1 = new DatagramPacket(a,a.length, InetAddress.getByName("224.0.1.1"),6666);//数据,大小,服务端的IP,服务端的端口
接收端
//修改前 //1.创建接收端对象,注册端口(人) System.out.println("=========接收端启动==============="); DatagramSocket socket2 = new DatagramSocket(6666); //修改后 //1.创建接收端对象,注册端口(人) System.out.println("=========接收端启动==============="); MulticastSocket socket2 = new MulticastSocket(6666); //绑定组播IP(JDK开始过时的API) socket2.joinGroup(InetAddress.getByName("224.0.1.1"));