(UDP通讯的实现)
1 UDP通信介绍
(面向无链接的一个传输协议——>不会创建连接——>效率高)
(发送数据要经行封包操作——>使用DatagramPacket类——>底层是UDP)
(DatagramPacket——>数据封包——>发送数据和接收数据都要去包装对象!!!必须是字节数组!!!——接收2个参数,发送4个参数)
(DatagramSocket——>发送或接收数据报包)
(注意这两个类的方法,构造方法,UDP通信编程基本步骤)
1 和TCP的区别
UDP协议与之前讲到的TCP协议不同,是面向无连接的,双方不需要建立连接便可通信。UDP通信所发送的数据需要进行封包操作(使用DatagramPacket类),然后才能接收或发送(使用DatagramSocket类)。
2 DatagramPacket:数据容器(封包)的作用
此类表示数据报包。 数据报包用来实现封包的功能。
常用方法:
方法名 | 使用说明 |
---|---|
DatagramPacket(byte[] buf, int length) | 构造数据报包,用来接收长度为 length 的数据包 |
DatagramPacket(byte[] buf, int length, InetAddress address, int port) | 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号 |
getAddress() | 获取发送或接收方计算机的IP地址,此数据报将要发往该机器或者是从该机器接收到的 |
getData() | 获取发送或接收的数据 |
setData(byte[] buf) | 设置发送的数据 |
3 DatagramSocket:用于发送或接收数据报包
当服务器要向客户端发送数据时,需要在服务器端产生一个DatagramSocket对象,在客户端产生一个DatagramSocket对象。服务器端的DatagramSocket将DatagramPacket发送到网络上,然后被客户端的DatagramSocket接收。
DatagramSocket有两种常用的构造函数。一种是无需任何参数的,常用于客户端;另一种需要指定端口,常用于服务器端。如下所示:
- DatagramSocket() :构造数据报套接字并将其绑定到本地主机上任何可用的端口。
- DatagramSocket(int port) :创建数据报套接字并将其绑定到本地主机上的指定端口。
常用方法:
方法名 | 使用说明 |
---|---|
send(DatagramPacket p) | 从此套接字发送数据报包 |
receive(DatagramPacket p) | 从此套接字接收数据报包 |
close() | 关闭此数据报套接字 |
4 UDP通信编程基本步骤:
- 创建客户端的DatagramSocket,创建时,定义客户端的监听端口。
- 创建服务器端的DatagramSocket,创建时,定义服务器端的监听端口。
- 在服务器端定义DatagramPacket对象,封装待发送的数据包。
- 客户端将数据报包发送出去。
- 服务器端接收数据报包。
2 创建服务端
(1 创建服务端接收数据的DatagramSocket对象——>使用完要关闭,用try-with-resource,给定服务端接收数据的端口)
(2 创建数据缓存区——>byte类型数组)
(3 创建数据报包对象——>给定2个参数——>缓冲区数组,缓冲区数组的长度)
(4 等待接收客户端所发送的数据——>datagramSocket.receive()😉
(5 取出数据——>getData();返回的是字节类型,转换成字符串类型,传长度时要传.getLength(),不能是数组的长度)
public class UDPServer {
public static void main(String[] args) {
//创建服务端接收数据的DatagramSocket对象
try(DatagramSocket datagramSocket = new DatagramSocket(9999)){
//创建数据缓存区
byte[] b = new byte[1024];
//创建数据报包对象
DatagramPacket dp =new DatagramPacket(b,b.length);
//等待接收客户端所发送的数据
datagramSocket.receive(dp);
//取数据
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(str);
}catch(Exception e){
e.printStackTrace();
}
}
}
3 创建客户端
(1 创建数据发送对象 DatagramSocket,需要指定消息的发送端口——>注意在本机上端口号不能一样
——>TCP通讯中服务端和客户端的端口是一个,UDP中是两个不同的端口,因为没有连接)
(2 消息需要进行类型转换,转换成字节数组数据类型——>把字符串转换成字节数组)
(3 创建数据报包装对象DatagramPacket——>给定4个参数——>数组,数组长度,new InetSocketAddress发送目标IP,端口)
(4 发送消息——>datagramSocket.send()😉
public class UDPClient {
public static void main(String[] args) {
//创建数据发送对象 DatagramSocket,需要指定消息的发送端口
try(DatagramSocket ds = new DatagramSocket(8888)) {
//消息需要进行类型转换,转换成字节数据类型。
byte[] b = "嘉".getBytes();
//创建数据报包装对象DatagramPacket
DatagramPacket dp = new DatagramPacket(b, b.length, new InetSocketAddress("127.0.0.1", 9999));
//发送消息
ds.send(dp);
}catch(Exception e){
e.printStackTrace();
}
}
}
4 基本数据类型—创建服务端
(1 创建服务端接收数据的DatagramSocket对象)
(2 创建数据缓存区——>byte类型数组)
(3 创建数据报包对象——>给定2个参数——>缓冲区数组,缓冲区数组的长度)
(4 等待接收客户端所发送的数据——>datagramSocket.receive()😉
(5 接收基本类型数据——>使用数据流DataInputStream ——>ByteArrayInputStream可以直接从数组里读对象,然后把读到的信息打印出来)
public class BasicTypeUDPServer {
public static void main(String[] args) {
try(DatagramSocket datagramSocket = new DatagramSocket(9999)){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
datagramSocket.receive(dp);
//实现数据类型转换
try(DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dp.getData()))){
//通过基本数据数据流对象获取传递的数据
System.out.println(dis.readLong());
}
}catch(Exception e){
e.printStackTrace();
}
}
}
v
5 基本数据类型—创建客户端
(1 创建DatagramSocket对象,给定端口)
(2 创建DataOutputStream和ByteArrayInputStream流对象)
(3 把一个基本数据类型通过数据流,写给了字节数组)
(4 将基本数据类型数据转换成字节数组类型)
(5 创建数据报包装对象DatagramPacket——>给定4个参数——>数组,数组长度,new InetSocketAddress发送目标IP,端口)
(6 发送消息——>datagramSocket.send()😉
public class BasicTypeClient {
public static void main(String[] args) {
long n = 2000L;
try(DatagramSocket datagramSocket = new DatagramSocket(9000);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos)){
dos.writeLong(n);
//将基本数据类型数据转换成字节数组类型
byte[] arr = bos.toByteArray();
DatagramPacket dp = new DatagramPacket(arr,arr.length,new InetSocketAddress("127.0.0.1",9999));
datagramSocket.send(dp);
}catch (Exception e){
e.printStackTrace();
}
}
}
6 对象类型—创建服务端
(当该对象需要在网络上传输时,一定要实现Serializable接口——>因为要用对象流来操作)
(服务端——>前面的都一样——>创建DatagramSocket对象,准备DatagramPacket(袋子),接收数据——>对接收的内容做类型转换ObjectInputStream和ByteArrayInputStream对象——>打印读到的数据)
创建Person类
/**
* 当该对象需要在网络上传输时,一定要实现Serializable接口
*/
public class Person implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
创建服务端
public class ObjectTypeServer {
public static void main(String[] args) {
try(DatagramSocket datagramSocket = new DatagramSocket(9999);){
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
datagramSocket.receive(dp);
//对接收的内容做类型转换
try(ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(dp.getData()))){
System.out.println(objectInputStream.readObject());
}
}catch(Exception e){
e.printStackTrace();
}
}
}
7 对象类型—创建客户端
(创建DatagramSocket ,ByteArrayOutputStream ,ObjectOutputStream 对象)
(创建自定义对象,get,set方法——>然后把这个对象通过objectOutputStream写出去)
(将数据包装成DatagramPacket 对象——>给定4个参数)
(发送消息——>datagramSocket.send()😉
public class ObjectTypeClient {
public static void main(String[] args) {
try(DatagramSocket datagramSocket = new DatagramSocket(8888);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)){
Person p = new Person();
p.setName("Oldlu");
p.setAge(18);
oos.writeObject(p);
byte[] arr = bos.toByteArray();
DatagramPacket dp = new DatagramPacket(arr,arr.length,new InetSocketAddress("127.0.0.1",9999));
datagramSocket.send(dp);
}catch(Exception e){
e.printStackTrace();
}
}
}
8 网络编程总结
-
端口是虚拟的概念,并不是说在主机上真的有若干个端口。
-
在www上,每一信息资源都有统一且唯一的地址,该地址就叫URL(Uniform Resource Locator),它是www的统一资源定位符。
-
TCP与UDP的区别
- TCP是面向连接的,传输数据安全,稳定,效率相对较低。
- UDP是面向无连接的,传输数据不安全,效率较高。
-
Socket通信是一种基于TCP协议,建立稳定连接的点对点的通信。
-
网络编程是由java.net包来提供网络功能。
- InetAddress:封装计算机的IP地址和DNS(没有端口信息!)。
- InetSocketAddress:包含IP和端口,常用于Socket通信。
- URL:以使用它的各种方法来对URL对象进行分割、合并等处理。
-
基于TCP协议的Socket编程和通信
- “请求-响应”模式:
- Socket类:发送TCP消息。
- ServerSocket类:创建服务器。
- “请求-响应”模式:
-
UDP通讯的实现
- DatagramSocket:用于发送或接收数据报包。
- 常用方法:send()、receive()、 close()。
-
DatagramPacket:数据容器(封包)的作用
- 常用方法:构造方法、getAddrress(获取发送或接收方计算机的IP地址)、getData(获取发送或接收的数据)、setData(设置发送的数据)。