【JavaSE】【网络编程】UDP数据报套接字编程

目录

  • 一、网络编程简介
  • 二、Socket套接字
  • 三、TCP/UDP简介
    • 3.1 有连接 vs 无连接
    • 3.2 可靠传输 vs 不可靠传输
    • 3.3 面向字节流 vs 面向数据报
    • 3.4 双向工 vs 单行工
  • 四、UDP数据报套接字编程
    • 4.1 API介绍
      • 4.1.1 DatagramSocket类
        • 4.1.1.1 构造方法
        • 4.1.1.2 主要方法
      • 4.1.2 DatagramPocket类
        • 4.1.2.1 构造方法
        • 4.1.2.2 主要方法
      • 4.1.3 使用上述类创建回显服务器-客户端
        • 4.1.3.1 回显服务器UdpEchoServer
        • 4.1.3.2 回显客户端UdpEchoClient

一、网络编程简介

网络编程:

网络编程,指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。

网络编程涉及基本概念:

一次网络数据传输时:
发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。
接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。
收发端:发送端和接收端两端,也简称为收发端。

请求和响应 :
一般来说,获取一个网络资源,涉及到两次网络数据传输:
第一次:请求数据的发送。
第二次:响应数据的发送。

客户端和服务端
服务端:在常见的网络数据传输场景下,把提供服务的一方进程,称为服务端,可以提供对外服务。
客户端:获取服务的一方进程,称为客户端。

二、Socket套接字

Socket套接字:Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。

Socket套接字主要针对传输层协议划分为如下三类:

  1. 流套接字:使用传输层TCP协议。
  2. 数据报套接字:使用传输层UDP协议。
  3. 原始套接字:用于自定义传输层协议。

三、TCP/UDP简介

socket api :传输层提供给应用层的API。
传输层的两个核心协议是:TCP与UDP协议。

  • TCP协议:有连接,可靠传输,面向字节流,全双工的协议。
  • UDP协议:无连接,不可靠传输,面向数据报,全双工的协议。

3.1 有连接 vs 无连接

有/无连接:是一个抽象的概念,虚拟的逻辑上的连接。就像前面的链表的学习一样,物理上不连续,但通过节点之间的关联使其逻辑上连续。

TCP协议中:保存了对端的信息,让两个通信之间的设备有连接。就如AB通信,A保存B信息,B保存A信息。

UDP协议中:UDP本身不保存对端信息,但可以自己使用代码保存。

3.2 可靠传输 vs 不可靠传输

丢包: 网络上数据发生丢失的情况就是丢包。

传输中丢包情况造成原因:

  1. 当光/电/电磁信号,受到外界的干扰。
  2. 网络世界是通过交换机,路由器组建起来的。而交换机,路由器就像十字路口一样,当某个时间点,实际转发的数据超过设备能转发的上限的时候,就会“堵车”,造成丢包。

可靠传输:不是保证数据报100%到达,不造成一点丢失。而是尽可能提高传输成功的概率,如果丢包还会进行记录。

不可靠传输:在发出数据后就不管了。

3.3 面向字节流 vs 面向数据报

面向数据流:读写数据(读–>接收数据,写–> 发送数据)的时候,以字节为单位。支持读写任意长度,有粘包问题。
面向数据报:读写数据(读–>接收数据,写–> 发送数据)的时候,以一个数据报为单位。有长度限制。

3.4 双向工 vs 单行工

全双工:读写数据(读–>接收数据,写–> 发送数据),支持双向通信,能读能写。
单双工:面向数据流:读写数据(读–>接收数据,写–> 发送数据),只支持单向通信,要么读要么写。

四、UDP数据报套接字编程

计算机中的文件通常是一个广义的概念,文件除了指代一些我们常说的文件外,还能指代一些硬件设备。操作系统管理硬件设备也是抽象成文件。

4.1 API介绍

4.1.1 DatagramSocket类

DatagramSocket 是UDP Socket,⽤于发送和接收UDP数据报。

4.1.1.1 构造方法
方法签名方法说明
public DatagramSocket() throws SocketException创建⼀个UDP数据报套接字的Socket,绑定到本机任意⼀个随机端⼝(⼀般⽤于客⼾端)
public DatagramSocket(int port) throws SocketException创建⼀个UDP数据报套接字的Socket,绑定到本机指定的端⼝(⼀般⽤于服务端)
public DatagramSocket(int port, InetAddress laddr) throws SocketException创建⼀个UDP数据报套接字的Socket,绑定到指定的IP即laddr和端⼝port
public DatagramSocket(SocketAddress bindaddr) throws SocketException创建⼀个UDP数据报套接字的Socket,绑定到bindaddr指定的IP和端⼝
4.1.1.2 主要方法
方法签名作用
public void send(DatagramPacket p) throws IOException从此套接字发送数据报包(不会阻塞等待,直接发送)
public synchronized void receive(DatagramPacket p) throws IOException从此套接字接收数据报(如果没有接收到数据报,该⽅法会阻塞等待)
public void close()关闭此数据报套接字

4.1.2 DatagramPocket类

DatagramPacket是UDP Socket发送和接收的数据报。

4.1.2.1 构造方法
方法签名作用
public DatagramPacket(byte buf[ ], int length)构造⼀个DatagramPacket以⽤来接收数据报,接收的数据保存在字节数组(第⼀个参数buf)中,接收指定⻓度(第⼆个参数length)
public DatagramPacket(byte buf[ ], int offset, int length)构造⼀个DatagramPacket以⽤来接收数据报,接收的数据保存在字节数组(第⼀个参数buf)中,接收指定⻓度(第⼆个参数length)从buf的下标offset位置开始接收
public DatagramPacket(byte buf[], int offset, int length, SocketAddress address)构造⼀个DatagramPacket以⽤来发送数据报,发送的数据为字节数组(第⼀个参数buf)中,从offset到指定⻓度(第⼆个参数length)。address指定⽬的主机的IP和端⼝号
public DatagramPacket(byte buf[ ], int offset, int length, InetAddress address, int port)构造⼀DatagramPacket以⽤来发送数据报,发送的数据为字节数组(第⼀个参数buf)中,从0到指定⻓度(第⼆个参数length)。address指定⽬的主机的IP,port指定⽬的主机的端⼝号
public DatagramPacket(byte buf[ ], int length, SocketAddress address)构造⼀个DatagramPacket以⽤来发送数据报,发送的数据为字节数组(第⼀个参数buf)中,从0到指定⻓度(第⼆个参数length)。address指定⽬的主机的IP和端⼝号
public DatagramPacket(byte buf[ ], int length, InetAddress address, int port)构造⼀个DatagramPacket以⽤来接收数据报,接收的数据保存在字节数组(第⼀个参数buf)中,接收指定⻓度(第⼆个参数length)address指定⽬的主机的IP,port指定⽬的主机的端⼝号
4.1.2.2 主要方法
方法签名作用
public synchronized byte[ ] getData()获取数据报中的数据
public synchronized int getPort()从接收的数据报中,获取发送端主机的端⼝号;或从发送的数据报中,获取接收端主机端⼝号
public synchronized InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址

4.1.3 使用上述类创建回显服务器-客户端

回显:请求是啥,相应就是啥。

4.1.3.1 回显服务器UdpEchoServer
  1. 先创建一个成员变量:Socket对象,用于接收发送数据报。private DatagramSocket socket = null;
  2. 构造方法,指定一个固定端口号给服务器使用,将Socket使用这个端口号实例化。
public UdpEchoServer(int port) throws SocketException{socket = new DatagramSocket(port);}
  1. 接下来在start方法中编写服务器实现逻辑。由于服务器是要7*24小时工作的,所以在一个死循环中实现。
  2. 读取请求并解析;
    4.1 构造一个DatagramPocket对象,初始化为0(不是null),用于保存UDP的载荷部分。
    DatagramPacket requestPacket = new DatagramPacket(new byte[2024],2024);
    4.2 读取请求socket.receive(requestPacket);
    4.3 把读取到有效数据的解析为字符串。
    通过getData方法获取DatagramPacket 中的字节数组,getLength方法获取DatagramPacket 有效数据长度,根据字节数组构造字符串。
    String request = new String(requestPacket.getData(), 0 ,requestPacket.getLength());
  3. 根据请求计算响应,由于是回显服务器,直接请求就是响应。
String response = product(request);private String product(String request) {return request;}
  1. 把响应返回给客户端,通过getBytes方法拿到字符串中的字节数据,getBytes().length拿到字节长度,getSocketAddress方法拿到客户端的端口和IP。
socket.send(new DatagramPacket(request.getBytes(),request.getBytes().length,
requestPacket.getSocketAddress()));
  1. 打印一个日志记录此次交互过程。
System.out.printf([%s:%d],request:%s,response:%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);
  1. 总代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {//先创建一个成员变量:Socket对象,用于接收发送数据报private DatagramSocket socket = null;//构造方法,指定一个固定端口号给服务器使用,将Socket使用这个端口号实例化public UdpEchoServer(int port) throws SocketException{socket = new DatagramSocket(port);}public void start() throws IOException {while (true) {//构造一个DatagramPocket对象,初始化为0(不是null),用于保存UDP的载荷部分。DatagramPacket requestPacket = new DatagramPacket(new byte[2024], 2024);//接收请求socket.receive(requestPacket);//把读取到有效数据的解析为字符串String request = new String(requestPacket.getData(),0,requestPacket.getLength());//计算响应String response = product(request);//把响应返回给客户端socket.send(new DatagramPacket(request.getBytes(),request.getBytes().length,requestPacket.getSocketAddress()));//打印一个日志System.out.printf("[%s : %d], request:%s , response:%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}private String product(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer server = new UdpEchoServer(6666);server.start();}
}
4.1.3.2 回显客户端UdpEchoClient
  1. 先创建一个成员变量:Socket对象,用于接收发送数据报private DatagramSocket socket = null;
  2. UDP 本身不保存对端的信息, 就自己的代码中保存一下.
	private String serverIp;private int port;
  1. 构造方法是要指定访问的服务器的地址。
public UdpEchoClient(String serverIp,int port) throws SocketException {this.serverIp = serverIp;this.port = port;socket = new DatagramSocket();}
  1. 从控制台读取用户输入的内容。
			System.out.println("请输入要传输的内容");Scanner scanner = new Scanner(System.in);if (!scanner.hasNext()) {break;}String request =scanner.next();
  1. 发送数据报,把请求发送给服务器, 需要构造 DatagramPacket 对象。 构造过程中, 不光要构造载荷, 还要设置服务器的 IP 和端口号。
socket.send(new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),port));
  1. 接收服务器的响应
DatagramPacket responsePacket = new DatagramPacket(new byte[2024],2024);
socket.receive(responsePacket);
  1. 从服务器读取的数据进行解析, 打印出来.
String response = new String(responsePacket.getData(),0,responsePacket.getData().length);System.out.println(response);
  1. 总代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {//先创建一个成员变量:Socket对象,用于接收发送数据报private DatagramSocket socket = null;// UDP 本身不保存对端的信息, 自己的代码中保存一下private String serverIp;private int port;public UdpEchoClient(String serverIp,int port) throws SocketException {this.serverIp = serverIp;this.port = port;socket = new DatagramSocket();}public void start() throws IOException {while (true) {// 1. 从控制台读取用户输入的内容.System.out.println("请输入要传输的内容");Scanner scanner = new Scanner(System.in);if (!scanner.hasNext()) {break;}String request =scanner.next();//  发送数据报.把请求发送给服务器, 需要构造 DatagramPacket 对象。 构造过程中, 不光要构造载荷, 还要设置服务器的 IP 和端口号。socket.send(new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),port));//接收服务器的响应DatagramPacket responsePacket = new DatagramPacket(new byte[2024],2024);socket.receive(responsePacket);//从服务器读取的数据进行解析, 打印出来.String response = new String(responsePacket.getData(),0,responsePacket.getData().length);System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1",6666);client.start();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【K8S系列】Kubernetes Pod节点ImagePullBackOff 状态及解决方案详解【已解决】

在 Kubernetes 中,当某个 Pod 的容器无法从指定的镜像仓库拉取镜像时,Pod 的状态会变为 ImagePullBackOff。这通常是因为指定的镜像不存在、镜像标签错误、认证失败或网络问题等原因。 以下是关于 ImagePullBackOff 的详细分析及解决方案。 1. ImagePull…

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源 由于需要在 Linux 环境下进行一些测试工作,于是决定使用 VMware 虚拟化软件来安装 Ubuntu 24.04 .1操作系统。考虑到测试过程中需要访问 Github ,要使用Docker拉去镜像等外部网络资源,因此产…

前列腺分割:基于边界加权(解决弱边界)、域自适应(少样本)

前列腺分割:基于边界加权(解决弱边界)、域自适应(少样本) 理解发现规律论文大纲观察1. 观察行为2. 变量分析3. 假设提出4. 验证过程 解法拆解 论文:Boundary-weighted Domain Adaptive Neural Network for …

鼠标绘制轮廓

需要对label进行提升&#xff0c;新建MyLabel类&#xff0c;并将其提升到label控件上&#xff0c;详见上篇控件提升 mylabelmouse.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_mylabelmouse.h" #include <QMenu> #include "My…

C语言-详细讲解-冒泡排序与选择排序

1.冒泡排序 冒泡排序是一种比较简单的排序算法。它重复地走访要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换&#xff0c;也就是说该数列已经排序完成。这个名字的由来是因为越小&a…

MATLAB常见数学运算函数

MATLAB中含有许多有用的函数,可以随时调用。 a b s abs abs函数 a b s abs abs函数在MATLAB中可以求绝对值,也可以求复数的模长:c e i l ceil ceil函数 向正无穷四舍五入(如果有小数,就向正方向进一)f l o o r floor floor函数 向负无穷四舍五入(如果有小数,就向负方向…

SpringBoot 集成 Sharding-JDBC(一):数据分片

在深入探讨 Sharding-JDBC 之前&#xff0c;建议读者先了解数据库分库分表的基本概念和应用场景。如果您还没有阅读过相关的内容&#xff0c;可以先阅读我们之前的文章&#xff1a; 关系型数据库海量数据存储策略-CSDN博客 这篇文章将帮助您更好地理解分库分表的基本原理和实现…

go-zero(六) JWT鉴权

go-zero JWT鉴权 还记得我们之前登录功能&#xff0c;返回的信息是token吗&#xff1f; 这个token其实就是JSON Web Token简称JWT,它是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用环境间安全地传递声明信息。 它是一种基于 JSON 的令牌&#xf…

ZYNQ程序固化——ZYNQ学习笔记7

一、ZYNQ启动过程 二、 SD卡启动实操 1、对ZYNQ进行配置添加Flash 2、添加SD卡 3、重新生成硬件信息 4、创建vitis工程文件 5、勾选板级支持包 6、对系统工程进行整体编译&#xff0c;生成两个Debug文件&#xff0c;如图所示。 7、插入SD卡&#xff0c;格式化为 8、考入BOOT.…

进程其他知识点

/* #include <stdlib.h> void exit(int status); #include <unistd.h> void _exit(int status); status 参数&#xff1a;是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。 */ #include <stdio.h> #include <stdlib.h> #include &…

Android ART知多少?

Android 虚拟机 ART&#xff08;Android Runtime&#xff09;是 Android 平台上的应用程序运行时环境&#xff0c;用于执行应用程序的字节码。ART 自 Android 5.0&#xff08;Lollipop&#xff09;开始取代了 Dalvik&#xff0c;成为 Android 的默认运行时环境。本文将从以下几…

C++ —— 剑斩旧我 破茧成蝶—C++11

江河入海&#xff0c;知识涌动&#xff0c;这是我参与江海计划的第2篇。 目录 1. C11的发展历史 2. 列表初始化 2.1 C98传统的{} 2.2 C11中的{} 2.3 C11中的std::initializer_list 3. 右值引用和移动语义 3.1 左值和右值 3.2 左值引用和右值引用 3.3 引用延长生命周期…

推荐15个2024最新精选wordpress模板

以下是推荐的15个2024年最新精选WordPress模板&#xff0c;轻量级且SEO优化良好&#xff0c;适合需要高性能网站的用户。中文wordpress模板适合搭建企业官网使用。英文wordpress模板&#xff0c;适合B2C网站搭建&#xff0c;功能强大且兼容性好&#xff0c;是许多专业外贸网站的…

(计算机毕设)基于SpringBoot+Vue的房屋租赁系统的设计与实现

博主可接毕设设计&#xff01;&#xff01;&#xff01; 各种毕业设计源码只要是你有的题目我这里都有源码 摘 要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互…

python蓝桥杯刷题2

1.最短路 题解&#xff1a;这个采用暴力枚举&#xff0c;自己数一下就好了 2.门牌制作 题解&#xff1a;门牌号从1到2020&#xff0c;使用for循环遍历一遍&#xff0c;因为range函数无法调用最后一个数字&#xff0c;所以设置成1到2021即可&#xff0c;然后每一次for循环&…

深度学习中的Pixel Shuffle和Pixel Unshuffle:图像超分辨率的秘密武器

在深度学习的计算机视觉任务中&#xff0c;提升图像分辨率和压缩特征图是重要需求。Pixel Shuffle和Pixel Unshuffle是在超分辨率、图像生成等任务中常用的操作&#xff0c;能够通过转换空间维度和通道维度来优化图像特征表示。本篇文章将深入介绍这两种操作的原理&#xff0c;…

Unity类银河战士恶魔城学习总结(P132 Merge skill tree with skill Manager 把技能树和冲刺技能相组合)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了解锁技能后才可以使用技能&#xff0c;先完成了冲刺技能的锁定解锁 Dash_Skill.cs using System.Collections; using System…

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 捕获组 普通捕获组 命名捕获组 PS:非捕获组 正则表达式在线测试: 正则在线测试工具 …

qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能

一、前言 主要功能如下&#xff1a; 1.实现文件夹的下载和删除&#xff0c;网上很多资料都是单独对某个路径的文件操作的&#xff0c;并不能对文件夹操作 2.实现目标机中含中文名称自动转码&#xff0c;有些系统编码方式不同&#xff0c;下载出来的文件会乱码 3.实现ftp功能…

HCIP --OSI七层参考模型回顾、TCP/UDP协议复习

目录 一、OSI 二、重要的三个协议报头格式 名词注解 MTU 封装 解封装 PDU ARP DNS TCP/IP与OSI的区别 三、数据包转发过程 四、获取目标ip地址方式 五、获取目标mac地址方式 六、交换机的工作原理 七、TCP/UDP TCP&#xff08;Transmission Control Protocol&a…