欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > 【Javaee】网络编程-UDP基础

【Javaee】网络编程-UDP基础

2024/10/23 23:19:52 来源:https://blog.csdn.net/yc_xym/article/details/143043164  浏览:    关键词:【Javaee】网络编程-UDP基础

  前言

UDP是一个高效、快速、简单的传输协议,适合于需要低延迟和实时性的应用

本篇将介绍UDP相关的api,并使用UDP构建回显服务器程序。


一.UDP与TCP

特点

UDP:无连接,不可靠,面向数据报,全双工。

TCP:有连接,可靠,面向字节流,全双工。

何为连接

此处所说的连接是抽象的连接,并不是实际两根线的相连,是指通信双方是否保留对方的信息(如IP地址,端口号)。

UDP是无连接的,通信双方不会保留对方的地址。

TCP是有连接的,通信双方保留着对方的地址。

何为可靠?

可靠指的是通信双方是否关注信息正确的传递到对方手上,可靠指会尽可能的确保数据传输到对方,不可靠是不关心数据是否传输过去。 

UDP是不可靠的,指的是当通信出现问题时,会直接把数据包丢弃,不会进行重传。

TCP是可靠的,指通信出现问题时,有着应答响应延时重传机制,防止数据的丢失

面向数据报与面向字节流

两种协议的传输单位不同。

数据报是一种专门为网络通信传输构造的特殊结构的传输单位,将需要传输的数据打包成一个整体。

UDP协议传输时,以一整个数据报为单位进行传输。

TCP协议面向字节流指的是数据被视为一个连续的字节序列,发送 方将数据拆分为字节流发送,而接收方将这些字节流重新组装成原始数据

全双工与半双工

全双工:一个通信信道,可以双向通信(既可以发送数据,也可以同时接收数据)

半双工:只能单向通信(接收数据与发送数据不能同时发送)

二.UDP的常用api

对于UDP来说,主要提供了两个核心api,即DatagramSocketDatagramPacket相当于网卡的遥控器)

1.DatagramSocket

1)构造方法

方法签名方法说明
DatagramSocket()

创建⼀个UDP数据报套接字的Socket,绑定到本机任意一个

随机端口(一般用于客户端)

DatagramSocket(int port)

创建⼀个UDP数据报套接字的Socket,绑定到本机指定的

端口(一般用于服务器)

2)DatagramSocket方法

方法签名方法说明
void receive(DatagramPacket)从此套接字接收数据报(如果没有接收到数据报,该⽅法会阻塞等待)
void send(DatagramPacket)从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()关闭此数据报套接字

2.DatagramPacket

1.构造方法

方法签名方法说明
DatagramPacket(byte[] buf, int length)构造⼀个DatagramPacket以⽤来接收数据报,接收的数据保存在字节数组(第⼀个参数buf)中,接收指定⻓度(第⼆个参数length)
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)构造⼀个DatagramPacket以⽤来发送数据报,发送的 数据为字节数组(第⼀个参数buf)中,从0到指定⻓度(第⼆个参数length)。address指定⽬的主机的IP 和端⼝号

2.DatagramPacket方法

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

当看方法,可能看的云里雾里,接下来通过代码来演示

三.UDP服务器端实现

1.代码实现

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpService {private DatagramSocket socket = null;public UdpService(int port) throws SocketException {socket = new DatagramSocket(9090);//参数是服务器绑定的端口}public void start() throws IOException {System.out.println("服务器开始运行");while (true) {//服务器需要反复的执行客户的请求DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);String request = new String(requestPacket.getData(), 0, requestPacket.getLength());String response = process(request);DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf("[%s:%d],服务器响应:%s,客户机请求:%s", requestPacket.getSocketAddress(),response, request);}}public String process(String request) {return request;//回显服务器,返回请求,不做其他操作}public static void main(String[] args) throws IOException {UdpService service=new UdpService(9090);service.start();}
}

2.代码解析

服务器的基本流程主要分为3个部分

1)读取请求并解析

DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);String request = new String(requestPacket.getData(), 0, requestPacket.getLength());

此段代码中,首先定义requestPacket数据报,确定数据报的大小,再接收客户端请求,放入数据报中,并解析请求信息。

2)根据请求计算响应【服务器最重要的环节】

 String response = process(request);public String process(String request) {return request;//回显服务器,返回请求,不做其他操作}

此代码实现的为回显服务器,将请求作为响应返回,不涉及其他逻辑

3)把响应写回给客户端,打印日志

 DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf("[%s:%d],服务器响应:%s,客户机请求:%s", requestPacket.getSocketAddress(),response, request);

定义responsePacket数据报,将response的信息打包好,定义好发送的ip地址和端口号,用send发送回客户端,并打印出客户端的ip 端口 请求信息和响应信息。

四.UDP客户端实现

1)代码实现

import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpCilent {private DatagramSocket socket=null;private String ServiceIP;private int ServicePort;public UdpCilent(String serviceIP,int servicePort) throws SocketException {this.ServiceIP=serviceIP;this.ServicePort=servicePort;socket=new DatagramSocket();}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner=new Scanner(System.in);while (true){System.out.println("->");String request= scanner.next();DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(this.ServiceIP),this.ServicePort);socket.send(requestPacket);DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpCilent cilent=new UdpCilent("127.0.0.1",9090);cilent.start();}
}

2)代码解析

1)从控制台中输入指令,将指令打包成数据报,数据报中要指明服务器的ip地址和端口号,才能将数据发送给对应的服务器处理

public class UdpCilent {private DatagramSocket socket=null;private String ServiceIP;private int ServicePort;public UdpCilent(String serviceIP,int servicePort) throws SocketException {this.ServiceIP=serviceIP;this.ServicePort=servicePort;socket=new DatagramSocket();}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner=new Scanner(System.in);while (true){System.out.println("->");String request= scanner.next();DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(this.ServiceIP),this.ServicePort);socket.send(requestPacket);

2)定义响应数据报,接收服务器处理完数据后的响应,并打印出来。

 DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);

3)启动程序,在new 对象中填入服务器的ip与端口号。

 public static void main(String[] args) throws IOException {UdpCilent cilent=new UdpCilent("127.0.0.1",9090);cilent.start();}

五.服务器与客户端执行过程

1.执行流程

1)首先控制台输入指令,客户端发送请求到服务器。

2)紧接着,服务器接收到请求,解除阻塞

3)服务器把得到的数据构造成string,执行process()方法对数据进行操作,返回操作结果response,并打包成数据报发送会客户端

4)客户端收到了返回的响应后,解除阻塞

5)打印日志,进入下一次循环

2.字典服务器

字典服务器提供着将客户端输入的英文转化中文,只需继承UDP服务器,并重写proces方法即可实现。

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;public class DictService extends UdpService{private Map<String,String> dict=new HashMap<String,String>();public DictService(int port) throws SocketException {super(port);dict.put("cat","猫");dict.put("dog","狗");dict.put("duck","鸭子");dict.put("fish","鱼");}@Overridepublic String process(String request) {return dict.getOrDefault(request,"未知单词");}public static void main(String[] args) throws IOException {DictService servicer=new DictService(9090);servicer.start();}


以上便是全部内容,如有不对,欢迎指正

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com