一切福田,不離方寸,從心而覓,感無不通。

Java Socket通信之UDP协议

一、什么是网络编程

网络编程:指网络上的主机,通过不同的进程,以编程的方式实现网络通信(数据通信本质是网络数据传输),其目的就是为了获取网络资源。
如何来理解呢?我们只需要记住是不同进程就可以。即便是同一台主机,只要是不同进程之间进行传输数据就属于网络编程。但是需要注意的是,一个进程获取资源,另外一个进程提供资源

发送端和接收端(发送端和接收端只是相对的,只是一次网络数据传输产生数据流之后的概念)
发送端:源主机
接收端:目的主机
收发端:既可以进行发送也可以接收数据

请求和响应
一般来讲,获取一个网络资源,涉及到两次网络数据传输:①请求数据发送 ②响应数据发送
比如,主机A给主机B发送消息之前,会请求主机B与它建立连接,之后主机B返回给它响应(同意建立连接)。

客户端和服务端
服务端:提供服务的一方
客户端:获取服务资源,并且可以保存资源在服务端。
举个栗子:在银行办业务
银行提供存款服务:用户(客户端)保存资源(现金)在银行(服务端)
银行提供取款服务:用户(客户端)获取服务端资源(银行替用户保管的现金)

常见的客户端服务端模型
核心流程:
①Client发送请求到Server
②Server根据请求,执行响应的业务处理
③Server返回响应,发送业务处理结果到Client
④Client根据响应数据,展示处理结果(展示获取到的资源/保存资源)

二、Socket套接字

Socket套接字:用于网络通信的技术,一般我们使用Socket进行网络程序开发,即网络编程
其主要针对传输层协议划分为三类:流套接字、数据报套接字、原始套接字。

流套接字

使用传输层TCP协议;
TCP:即Transmission Control Protocol(传输控制协议),传输层协议。
以下为TCP的特点:

  • 有连接(eg. 打电话要先拨号建立连接)
  • 可靠传输(发送方能知道对方是否收到)
  • 面向字节流(数据传输是基于IO流,在IO流没有关闭的情况下是无边界的数据,可以进行多次发送,也可以分开多次接收),以字节为基本单位,文件读写也是面向字节流的。
  • 有接收缓冲区,也有发送缓冲区
  • 大小不受限制
  • 全双工(A、B同时发送,即一个socket既能读也能写)

数据报套接字

使用传输层UDP协议;
UDP:即User Datagram Protocol(用户数据报协议),传输层协议。
以下为UDP的特点:

  • 无连接 (eg. 发微信,发送数据之前不需要建立连接)
  • 不可靠传输(UDP尽最大努力交付,即不保证可靠交付
  • 面向数据报(对于数据报来说,传输数据是一块一块的,发送一块数据假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。)
  • 有接收缓冲区,无发送缓冲区
  • 大小受限:一次最多传输64k
  • 全双工

原始套接字

原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。(这不是我们的重点)
面试题:TCP协议和UDP协议的区别
参考:TCP和UDP的区别
①报头不同 ②协议不同 ③特点不同

三、Java数据报套接字通讯模型

1. Socket UDP模型

操作系统把网络编程的一些相关操作(访问网络核心的硬件设备/网卡驱动等)封装起来了,提供了一组API供开发者使用。
对于UDP协议来讲,具有无连接、面向数据报的特征,即每次都是没有建立连接,一次发送全部数据报一次接受全部数据报。java中使用UDP协议通讯,主要基于DatagramSocket类来创建数据报套接字,并使用DatagramPacket描述一个发送或接收数据报。(DatagramSocket类描述一个socket对象,本质是一个文件描述符,表示网卡设备的文件,通过读写socket文件的方式操作网卡
对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,具体流程如下:
在这里插入图片描述

2. 常见的API

DatagramSocket API

DatagramSocket是UDP Socket,用于发送和接收UDP数据报。
DatagramSocket构造方法:

方法 说明
DatagramSocket() 创建一个UDP数据报套接字Socket,绑定到主机任意一个随机端口(客户端不需要绑定端口号)
DatagramSocket(int port) 创建一个UDP数据报套接字Socket,绑定到本机指定的端口(服务器)

DatagramSocket方法:

方法 说明
void receive(DatagramPacket p) 套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待,如果接收到数据,会返回一个DatagramPacket对象)
void send(DatagramPacketp) 套接字发送数据报包(不会阻塞等待,直接发送)
void close() 关闭此数据报套接字(UDP中的Socket生命周期跟随整个程序,所以close()方法不太需要关闭,如果进程结束就会释放相应资源)

DatagramPacket API

DatagramPacket是UDP Socket发送和接收的数据报。
DatagramPacket 构造方法:

方法 说明
DatagramPacket(byte[] buf, int length) 构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length)
DatagramPacket(byte[] buf, int offset, int length,SocketAddress address) 构造一个DatagramPacket以用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数length)。address指定目的主机的IP和端口号

DatagramPacket 方法:

方法 说明
InetAddress getAddress() 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort() 从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
byte[] getData() 获取数据报中的数据

构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。

InetSocketAddress API

InetSocketAddress ( SocketAddress 的子类 )构造方法:

方法 说明
InetSocketAddress(InetAddress addr, int port) 创建一个Socket地址,包含IP地址和端口号

四、UDP数据报套接字编程

以下两个小栗子,体现了UDP通信的业务逻辑,快来试试吧❤

1. 回显服务器

回显服务器:虽然是网络通信流程,但实际上仍是一台主机之间进行通信
回显服务器没有第③部分,相当于客户端请求是啥,返回给客户端的响应就是啥!
在这里插入图片描述
服务器代码:

 

客户端代码:

 

2.查字典服务器

服务器代码:

 

客户端代码:

ღ( ´・ᴗ・` )比心~

 

from:https://blog.csdn.net/fxt579810/article/details/123567128