一、UDP编程
1、UDP简介
在 TCP/IP 协议的传输层除了一个 TCP 协议之外,还有一个 UDP 协议。UDP (User Datagram Protocol)协议是用户数据报协议的简称,也用于网络数据的传输。虽然 UDP 协议是一种不太可靠的协议,但有时在需要较快地接收数据并且可以忍受较小错误的情况下,UDP 就会表现出更大的优势。
UDP的特点:
- 不安全
- 无连接
- 效率高
- UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内
下面是在Java 中使用 UDP 协议发送数据的步骤。
- 使用 DatagramSocket() 创建一个数据包套接字。
- 使用 DatagramPacket() 创建要发送的数据包。
- 使用 DatagramSocket 类的 send() 方法发送数据包。
接收 UDP 数据包的步骤如下:
- 使用 DatagramSocket 创建数据包套接字,并将其绑定到指定的端口。
- 使用 DatagramPacket 创建字节数组来接收数据包。
- 使用 DatagramPacket 类的 receive() 方法接收 UDP 包。
2、DatagramSocket和DatagramPacket
DatagramPacket:此类表示数据报包。每个包最大64kb。DatagramSocket:数据报套接字,表示用来发送和接收数据报包的套接字。
(1)DatagramPacket 类
java.net 包中的 DatagramPacket 类用来表示数据报包,数据报包用来实现无连接包投递服务,每个包最大64kb。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
构造方法:
构造方法 | 说明 |
---|---|
DatagramPacket(byte[] buf,int length) | 构造 DatagramPacket,用来接收长度为 length 的数据包。 |
DatagramPacket(byte[] buf,int offset,int length) | 构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。 |
DatagramPacket(byte[] buf,int length,InetAddress address,int port) | 构造 DatagramPacket,用来将长度为 length 的包发送到指定主机上的指定端口。 |
DatagramPacket(byte[] buf,int length, SocketAddress address) | 构造数据报包,用来将长度为 length 的包发送到指定主机上 的指定端口。 |
DatagramPacket(byte[] buf,int offset, int length,InetAddress address,int port) | 构造 DatagramPacket,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口。 |
DatagramPacket(byte[] buf,int offset, int length,SocketAddress address) | 构造数据报包,用来将长度为 length、偏移量为 offset 的包发 送到指定主机上的指定端口。 |
常用方法:
方法 | 说明 |
---|---|
InetAddress getAddress() | 返回某台机器的 IP 地址,此数据报将要发往该机器或者 从该机器接收。 |
byte[] getData() | 返回数据缓冲区。 |
int getLength() | 返回将要发送或者接收的数据的长度。 |
int getOffset() | 返回将要发送或者接收的数据的偏移量。 |
int getPort() | 返回某台远程主机的端口号,此数据报将要发往该主机或者从该主机接收。 |
getSocketAddress() | 获取要将此包发送或者发出此数据报的远程主机的SocketAddress(通常为 IP地址+端口号)。 |
void setAddress(InetAddress addr) | 设置要将此数据报发往的目的机器的IP地址。 |
void setData(byte[] buf) | 为此包设置数据缓冲区。 |
void setData(byte[] buf,int offset,int length) | 为此包设置数据缓冲区。 |
void setLength(int length) | 为此包设置长度。 |
void setPort(int port) | 设置要将此数据报发往的远程主机的端口号。 |
void setSocketAddress(SocketAddress address) | 设置要将此数据报发往的远程主机的SocketAddress(通常为 IP地址+端口号)。 |
(2)DatagramSocket 类
DatagramSocket 类用于表示发送和接收数据报包的套接字。数据报包套接字是包投递服务的发送或接收点。每个在数据报包套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
构造方法:
构造方法 | 说明 |
---|---|
DatagramSocket() | 构造数据报包套接字并将其绑定到本地主机上任何可用的端口。 |
DatagramSocket(int port) | 创建数据报包套接字并将其绑定到本地主机上的指定端口。 |
DatagramSocket(int portJnetAddress addr) | 创建数据报包套接字,将其绑定到指定的本地地址。 |
DatagramSocket(SocketAddress bindaddr) | 创建数据报包套接字,将其绑定到指定的本地套接字地址。 |
常用方法:
方法 | 说明 |
---|---|
void bind(SocketAddress addr) | 将此 DatagramSocket 绑定到特定的地址和端口。 |
void close() | 关闭此数据报包套接字。 |
void connect(InetAddress address,int port) | 将套接字连接到此套接字的远程地址。 |
void connect(SocketAddress addr) | 将此套接子连接到远程套接子地址(IP地址+端口号)。 |
void disconnect() | 断开套接字的连接。 |
InetAddress getInetAddress() | 返回此套接字连接的地址。 |
InetAddress getLocalAddress() | 获取套接字绑定的本地地址。 |
int getLocalPort() | 返回此套接字绑定的本地主机上的端口号。 |
int getPort() | 返回此套接字的端口。 |
3、使用UDP编程
(1)使用步骤
发送方:
- 实例化DatagramSocket对象;
- 构造DatagramPacket数据包,指定数据和数据的长度以及主机地址和端口号;
- 使用send(DatagramPacket p)方法发送数据包;
接收方:
- 实例化DatagramSocket对象,并绑定端口号;
- 将接收到的数据封装到DatagramPacket数据包中;
- 使用receive(DatagramPacket packet)接收数据;
- 获取数据包中的数据;
(2)示例
发送方:
package basis.stuJavaNet.StuUDP;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Sender {
public static void main(String[] args) {
sendMessage("localhost",7777,"你好啊");
}
public static void sendMessage(String ip,int port,String message){
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(message.getBytes(),message.getBytes().length, InetAddress.getByName(ip),port);
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
接收方:
package basis.stuJavaNet.StuUDP;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Receiver {
public static void main(String[] args) {
DatagramSocket socket = null;
try {
//1、实例化DatagramSocket对象,绑定端口号
socket = new DatagramSocket(7777);
//2、将接收的数据封装到数据包中
byte[] arr = new byte[1024];
DatagramPacket packet = new DatagramPacket(arr,arr.length);
System.out.println("等待接收数据~~~~~~~~~~");
//3、接收数据,将数据包从网络中取出来
socket.receive(packet);
//返回缓冲区
byte[] messages = packet.getData();
String result = new String(messages,0,messages.length);
//获取发送方IP
InetAddress address = packet.getAddress();
String ip = address.getHostAddress();
//获取端口
int port = packet.getPort();
System.out.println(ip+":"+port+"说:"+result);
} catch (Exception e) {
e.printStackTrace();
}
}
}