文章开头,先来回忆一下
什么是UDP?
UDP 的全称是 User Datagram Protocol,用户数据报协议。它不需要所谓的握手操作,从而加快了通信速度,允许网络上的其他主机在接收方同意通信之前进行数据传输。
UDP 的特点主要有?
UDP 能够支持容忍数据包丢失的带宽密集型应用程序
UDP 具有低延迟的特点 UDP 能够发送大量的数据包
UDP 能够允许 DNS 查找,DNS 是建立在 UDP 之上的应用层协议。
那不得不说一下
什么是TCP?
TCP 的全称是Transmission Control Protocol ,传输控制协议。它能够帮助你确定计算机连接到 Internet 以及它们之间的数据传输。通过三次握手来建立 TCP 连接,三次握手就是用来启动和确认 TCP 连接的过程。一旦连接建立后,就可以发送数据了,当数据传输完成后,会通过关闭虚拟电路来断开连接。
TCP 的主要特点有?
TCP 能够确保连接的建立和数据包的发送
TCP 支持错误重传机制 TCP 支持拥塞控制,能够在网络拥堵的情况下延迟发送 TCP
能够提供错误校验和,甄别有害的数据包。
UDP 和 TCP 的区别?
TCP 是面向连接的协议 。 UDP 是无连接的协议
TCP 在发送数据前先需要建立连接,然后再发送数据 。 UDP 无需建立连接就可以直接发送大量数据
TCP 会按照特定顺序重新排列数据包 。 UDP 数据包没有固定顺序,所有数据包都相互独立
TCP 传输的速度比较慢 。 UDP 的传输会更快 TCP 的头部字节有 20 字节 。 UDP 的头部字节只需要 8 个字节
TCP 是重量级的,在发送任何用户数据之前,TCP需要三次握手建立连接。 UDP 是轻量级的。没有跟踪连接,消息排序等。
TCP 会进行错误校验,并能够进行错误恢复 。 UDP 也会错误检查,但会丢弃错误的数据包
TCP 有发送确认。 UDP 没有发送确认
TCP 会使用握手协议,例如 SYN,SYN-ACK,ACK。 UDP无握手协议
TCP 是可靠的,因为它可以确保将数据传送到路由器。 UDP 中不能保证将数据传送到目标
UDP发送数据
接下进入正题,使用Java语言实现UDP发送数据与接收数据。
1.单播
单播的发送端具体流程
1.准备我们的数据源,如字符串数据,需要将其转为byte数组
2.准备你要传输的ip地址以及端口号
3.使用DatagramPacket进行将以上数据进行包装
4.通过DatagramSocket来发送我们的DatagramPacket
单播的接收端具体流程
1.准备好接收数组,用于接收数据缓冲
2.准备DatagramSocket,需要传入端口号,表示别人将从该端口进行发送数据
3.使用DatagramSocket进行数据接收,结果将返回在DatagramPacket对象中
4.调用DatagramPacket对象方法进行数据处理
发送:
package com.wxy.inetPackage;
import java.io.IOException;
import java.net.*;
public class DatagramSend {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket();
String str = "你好啊我是你的好朋友来自UDP";
byte[] bytes = str.getBytes();
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,inetAddress,port);
datagramSocket.send(datagramPacket);
datagramSocket.close();
}
}
接收:
package com.wxy.inetPackage;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class DatagramReceive {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(10086);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
datagramSocket.receive(datagramPacket);
//解析数据
byte[] data = datagramPacket.getData();
int length = datagramPacket.getLength();
InetAddress address = datagramPacket.getAddress();
int port = datagramPacket.getPort();
System.out.println("当前收到数据是:" + new String(data,0,length) + ",长度为" + length + ",发送端的地址是" + address + ",端口号是" + port);
datagramSocket.close();
}
}
2.组播
这里需要用到一个新的Socket,叫做MulticastSocket,使用它用来发送与接收我们的组播数据。其次需要注意的是,组播最好使用预留的224.0.0.0-224.0.0.255,其它与单播大致相同。
发送
package com.wxy.inetPackage;
import com.wxy.shiyanwu.User;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MulticastSend {
public static void main(String[] args) throws IOException {
MulticastSocket multicastSocket = new MulticastSocket();
InetAddress inetAddress = InetAddress.getByName("224.0.0.1");
String msg = "你好这里来自组播--";
byte[] bytes = msg.getBytes();
int port = 10000;
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,inetAddress,port);
multicastSocket.send(datagramPacket);
multicastSocket.close();
}
}
接收
package com.wxy.inetPackage;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MultiRec {
public static void main(String[] args) {
for (int i = 0;i < 3;i ++) {
new Thread(()->{
try (MulticastSocket multicastSocket = new MulticastSocket(10000);){
InetAddress inetAddress = InetAddress.getByName("224.0.0.1");
multicastSocket.joinGroup(inetAddress);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
multicastSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
System.out.println(Thread.currentThread().getName() + "收到数据:" + new String(data,0,datagramPacket.getLength()) + "hello");
}catch (IOException e){
e.printStackTrace();
}
}).start();
}
}
}
3.广播
广播更为简单,只需要将单播发送的ip改为广播IP即可,即255.255.255.255,接收就不上代码了,使用广播发送所有局域网上的IP都能接收得到,所以直接使用上方提供的单播接收也是可以接收到的。
package com.wxy.inetPackage;
import java.io.IOException;
import java.net.*;
public class DatagramSend {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket();
String str = "你好啊我是你的好朋友来自UDP";
byte[] bytes = str.getBytes();
InetAddress inetAddress = InetAddress.getByName("255.255.255.255");
int port = 10086;
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,inetAddress,port);
datagramSocket.send(datagramPacket);
datagramSocket.close();
}
}