【JavaEE精炼宝库】 网络编程套接字——初识网络编程 | UDP数据报套接字编程

news2024/11/13 9:02:11

文章目录

  • 一、网络编程基础
    • 1.1 网络编程的意义:
    • 1.2 网络编程的概念:
    • 1.3 网络编程的术语解释:
    • 1.4 常见的客户端服务端模型:
  • 二、Socket 套接字
    • 2.1 Socket 套接字的概念:
    • 2.2 Socket 套接字的分类:
  • 三、UDP数据报套接字编程
    • 3.1 API 介绍:
      • 3.1.1 DatagramSocket:
      • 3.1.2 DatagramPacket:
      • 3.1.3 InetSocketAddress:
    • 3.2 Java数据报套接字通信模型:
    • 3.3 代码示例:
      • 3.3.1 UDP Echo Server:
      • 3.3.2 UDP Echo Client:

一、网络编程基础

1.1 网络编程的意义:

网络编程的意义在于可以获取到丰富的网络资源。

用户在浏览器中,打开b站,实质是通过网络,获取到网络上的一个视频资源。
在这里插入图片描述

与本地打开视频文件类似,只是视频文件这个资源的来源是网络。相比本地资源来说,网络提供了更为丰富的网络资源。
在这里插入图片描述

所谓的网络资源,其实就是在网络中可以获取的各种数据资源。 而所有的网络资源,都是通过网络编程来进行数据传输的。

1.2 网络编程的概念:

网络编程:指网络上的主机,通过不同的进程,以编程的方式实现网络通信(或称为网络数据传输)。
在这里插入图片描述
注意:我们只要满足进程不同就行。所以即便是同一个主机,只要是不同进程,基于网络来传输数据,也属于网络编程。

1.3 网络编程的术语解释:

  • 发送端和接收端:

在一次网络数据传输时:

发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。

接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。

收发端:发送端和接收端两端,也简称为收发端。

注意:发送端和接收端只是相对的,只是⼀次网络数据传输产生数据流向后的概念。

  • 请求和响应:

请求(Request):是客户端向服务器发送的信息,用于请求特定的资源或执行特定的操作。
响应(Response):是服务器对客户端请求的回复。

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

举个栗子:在快餐店点一份炒饭,先要发起请求:点⼀份炒饭,再有快餐店提供的对应响应,提供一份炒饭。

  • 客户端和服务端:

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

客户端:获取服务的一方进程,称为客户端。

1.4 常见的客户端服务端模型:

最常见的场景,客户端是指给用户使用的程序,服务端是提供用户服务的程序。

  1. 客户端先发送请求到服务端。

  2. 服务端根据请求数据,执行相应的业务处理。

  3. 服务端返回响应,发送业务处理结果。

  4. 客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果)。

在这里插入图片描述

二、Socket 套接字

2.1 Socket 套接字的概念:

Socket套接字,是由系统提供用于网络通信的技术,是基于 TCP/IP 协议的网络通信的基本操作单元。 基于Socket套接字的网络程序开发就是网络编程。socket 可以简单理解为操作系统提供的网络编程的 API 统称。

2.2 Socket 套接字的分类:

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

  1. 流套接字:使用传输层TCP协议

TCP,即Transmission Control Protocol(传输控制协议),传输层协议。

其特点为:有连接,可靠传输,面向字节流,全双工。(术语不了解没有关系,在 2.2 的最后面有统一解释)

对于字节流来说,可以简单的理解为,传输数据是基于IO流,流式数据的特征就是在IO流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。

  1. 数据报套接字:使用传输层UDP协议

UDP,即User Datagram Protocol(用户数据报协议),传输层协议。

其特点为:无连接,不可靠传输,面向数据报,全双工。

对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据,假如100个字节,必须一次发送,接收也必须一次接收100个字节,而不能分100次,每次接收1个字节。

  1. 原始套接字:

原始套接字用于自定义传输层协议,用于读写内核没有处理的IP协议数据。我们不学习原始套接字,简单了解即可。

  • 术语解释:
  1. 有连接 | 无连接:

有连接:通信双方保存对方的信息。
无连接:通信双反不需要保存对方的信息。

  1. 可靠传输 | 不可靠传输:

注意:可靠不等于安全。

安全:传输的数据,是否容易被黑客截获掉,一旦被截获之后,是否会造成严重的影响。
可靠:传输的数据,尽可能(不是完全)地传输给对方。

可靠传输是有代价的,传输的效率会大打折扣。所以UDP 比 TCP 快。

  1. 面向字节流 | 面向数据报:

字节流,比喻成水流一样,读写操作非常灵活。数据报就不是了,传输数据的基本单位,是一个个的 UDP 数据报,一次读写,只能读写一个完整的 UDP 数据报。

  1. 全双工 | 半双工:

全双工:一条链路,能够进行双向通信。(TCP,UDP 都是全双工,后续代码中,创建 socket 对象,既可以读,也可以写)

半双工:一条链路,只能进行单向通信。

三、UDP数据报套接字编程

3.1 API 介绍:

主要涉及到两个类:DatagramSocket,DatagramPacket。

3.1.1 DatagramSocket:

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

  • DatagramSocket 构造方法:
方法签名方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端)。
DatagramSocket(int port)创建⼀个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端)。
  • DatagramSocket 普通方法:
方法签名方法说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)。
void send(DatagramPacket p)从此套接字发送数据报包(不会阻塞等待,直接发送)。
void close()关闭此数据报套接字。

3.1.2 DatagramPacket:

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 来创建。

3.1.3 InetSocketAddress:

  • InetSocketAddress(SocketAddress 的子类)构造方法:
方法签名方法说明
InetSocketAddress(InetAddress addr, int port)创建⼀个Socket地址,包含IP地址和端口号。

3.2 Java数据报套接字通信模型:

对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。

Java 中使用 UDP 协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用DatagramPacket
作为发送或接收的UDP数据报。对于一次发送及接收UDP数据报的流程如下:

在这里插入图片描述
以上只是一次发送端的UDP数据报发送,及接收端的数据报接收,并没有返回的数据。也就是只有请求,没有响应。对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,流程如下:
在这里插入图片描述

3.3 代码示例:

根据 3.2 的 Java 数据报套接字通信模型可以得到下面回显服务器
所谓回显就是请求和响应是相同的。即请求不做任何处理,直接返回。

3.3.1 UDP Echo Server:

在代码中细节点都有注释,这里就不再赘述。

服务器的端口号只要是在0 ~ 65535之间的没有被占用的端口号都行。

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    private DatagramSocket socket = null;

    //创建一个有端口号的 Udp 数据包套接字
    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while(true){
            //1.获取请求
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],0,4096);
            socket.receive(requestPacket);
            //2.根据请求计算响应
            //方便后续处理,这里直接将 byte 转化成 String
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            //计算响应
            String respond = this.process(request);
            //3.把响应写回到客户端
            DatagramPacket respondPacket = new DatagramPacket(respond.getBytes(),0,respond.getBytes().length
            ,requestPacket.getSocketAddress());
            socket.send(respondPacket);
            //打印日志
            System.out.printf("[%s:%d] req:%s resp:%s\n",requestPacket.getAddress(),requestPacket.getPort()
                    ,request,respond);
        }
    }
    //回显,所以直接返回即可
    public String process(String request){
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(9090);
        server.start();
    }
}

3.3.2 UDP Echo Client:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdpEchoClient {
    //Udp 数据报套接字
    private DatagramSocket socket = null;
    //服务器的 IP 地址
    private String serverIp = null;
    //服务器的端口号
    private int serverPort;
    public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        socket = new DatagramSocket();
    }
    public void start() throws IOException {
        System.out.println("客户端启动!");
        Scanner in = new Scanner(System.in);
        while(true){
            //提示用户从控制台输入数据
            System.out.print("请输入请求:");
            String request = in.next();
            //构造请求并发送
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),0,request.getBytes().length,
                    InetAddress.getByName(serverIp),serverPort);
            socket.send(requestPacket);
            //读取响应
            DatagramPacket respondPacket = new DatagramPacket(new byte[4096],0,4096);
            socket.receive(respondPacket);
            //打印响应到控制台
            String respond = new String(respondPacket.getData(),0,respondPacket.getLength());
            System.out.println(respond);
        }
    }

    public static void main(String[] args) throws IOException {
    	//输入自己电脑的IP地址
        UdpEchoClient client = new UdpEchoClient("172.20.10.4",9090);
        client.start();
    }
}
  • 查看自己电脑的IP地址
  1. 按下window + R,输入cmd:
    在这里插入图片描述
  2. 输入ipconfig
    在这里插入图片描述
  3. 查看IP地址:在这里插入图片描述

案例演示效果如下:

注意:要先启动服务器,再启动客户端。
在这里插入图片描述

这样在 IDEA 上只能打开一个客户端,所以我们要给我们的 IDEA 设置一下。具体操作流程如下:

第一步:

第二步:
在这里插入图片描述
第三步:
在这里插入图片描述
最后不要忘记点击ok。

结语:
其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

在这里插入图片描述

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

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

相关文章

24暑假算法刷题 | Day21 | LeetCode 669. 修剪二叉搜索树,108. 将有序数组转换为二叉搜索树,538. 把二叉搜索树转换为累加树

目录 669. 修剪二叉搜索树题目描述题解 108. 将有序数组转换为二叉搜索树题目描述题解 538. 把二叉搜索树转换为累加树题目描述题解 669. 修剪二叉搜索树 点此跳转题目链接 题目描述 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪…

Mac应用快速启动器:Alfred 5 for Mac 激活版

Alfred 5 是一款专为 macOS 系统设计的效率提升工具。这款软件以其快速启动和高效操作功能著称,通过使用快捷键来呼出输入界面,用户可以快速完成各种任务。 最新版本 Alfred 5.5 引入了一些新功能。其中包括整合了 ChatGPT 和 DALL-E,这意味…

Map的常见API

Map的常见API Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的 Map的遍历方式 map的遍历方式(键找值) package demo3;import java.util.HashMap; import java.util.Map; import java.util.Set;public class a1 {public static void main(String…

如何优化网站以提升UX设计质量

什么叫 UX 设计?UX 设计,即用户体验设计,是指为提升用户体验而进行的产品设计。 UX 在设计中,设计师通过调查和研究用户来掌握用户的需求和喜好,并利用这些信息来设计产品。设计师还会测试产品,以确保它们能…

xftp 如何链接 ubutn

一 如果你的ubutun 没有安装 openssh-server,那么是链接不上的,因此要先在ubutun 上一定要先安装openssh-server sudo apt install openssh-server 二 查看 ubutun 的ip 三 配置 xftp

导入vue3-引入富文本框编辑器-@wangeditor/editor库

效果图 下载依赖包 pureadmin/utils": "2.4.7 wangeditor/editor": "^5.1.23 wangeditor/editor-for-vue": "5.1.12定义公共组件 在src目录下定义 components/ReEditor/index.vue index.ts import editor from "./src/Editor.vue"…

BFS实现迷宫最短路径

结合队列的知识利用 广度优先遍历,通过对能走的路径的记录以及对走过路径的标记,进行多条路搜查 一、理论基础 如下图的迷宫: 选取所走方向(针对某一个位置)下,右,上,左&#xff0…

客户在哪儿AI——做真正管用的大客户获客方案

我们的目标是要打造一个真正“管用”的ToB大客户获客方案。以下是两个100%真实的案例,所有数据均为真实经营数据。一个是证明客户在哪儿AI对市场工作的颠覆性提升,另一个是证明客户在哪儿AI对决策层和销售工作的颠覆性提升。 客户在哪儿AI生产的是企业全…

C++模板——泛型编程

目录 1. 什么是泛型编程 2. 函数模板 2.1 定义格式 2.2 实例化及原理 2.3 参数匹配原则 3. 类模板 3.1 定义格式 3.2 实例化 4. 非类型模板参数 5. 模板的特化 5.1 概念 5.2 函数模板和类模板特化 6. 模板的分离编译 1. 什么是泛型编程 如何实现一个通用的加…

Windows下Pytorch入门深度学习环境安装与配置(CPU版本)

Windows下Pytorch入门深度学习环境安装与配置(CPU版本) 一、安装过程中各个软件的作用(一)Python(二)库 / 包 / package / library(三)PyTorch / Tensorflow(四&#xff…

详解yolov5和yolov8以及目标检测相关面试

一、与yoloV4相比,yoloV5的改进 输入端:在模型训练阶段,使用了Mosaic数据增强、自适应锚框计算、自适应图片缩放基准网络:使用了FOCUS结构和CSP结构Neck网络:在Backbone和最后的Head输出层之间插入FPN_PAN结构Head输出…

计算机二级题--文件 章节

之前写的有文件全部的知识点,这一篇主要针对计算机二级真题的整理。 需要备考计算机二级的小伙伴们先收藏起来吧。整理不易,不过有帮助记得点赞哦 1.相关概念考点: 1.文件指针指向的是文件缓冲区的位置,不是文件在读位置。 2.…

儿童洗衣机哪个牌子好?五大爆款机型倾情分享

在当今繁忙的生活中,儿童洗衣机已成为我们日常生活中不可或缺的家电。但是,面对市场上众多品牌的儿童洗衣机,那么,到底儿童洗衣机哪个牌子好?本次我将在这篇文章中探讨儿童洗衣机的选购策略,以帮助大家找到…

记录unraid docker更新的域名

背景:级联 一、安装内容 unraid更新docker,之前一直失败,修改网络后可以进行安装。 二、查看域名 查看域名,发现是走github的,怪不得有一些docker无法正常更新 三、解决方法 更改代理,这里为unraid的…

智慧教育解决方案

1. 智慧教育解决方案概述 智慧教育解决方案旨在通过教育改革实现四个转变:从以教为主到以学为主,从专业教育到通识与专业教育结合,从课堂教育到课内外结合,以及从结果评价到过程与结果评价结合。 2. 教育三维目标 教育三维目标…

避免工件精度受损:精准调整滚珠丝杆状态!

滚珠丝杆作为一种常用的传动装置,经过长期使用或者维护不当的情况下有时会发生弯曲或变形。弯曲不仅会对滚珠丝杆的精度和寿命造成影响,而且还会对整个机器系统的工作效率和安全性产生影响。那么,应该如何要避免滚珠丝杆弯曲对工件的影响呢&a…

Java数据结构与算法--链表(Linked List)

博客主页:誓则盟约系列专栏:Java SE关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 深入了解链表: 链表是一种常见的数据结构,它由一系列节点…

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】

请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权,请联系删除 转自: 芯爵ChipLord 2024年07月10日 12:00 浙江 文章目录 概述DRC的概念Tessent DRC检查的概述时钟相关检查扫描相关检查BIST规则检查预DFT时钟规则检查 …

zh echarts样式

记录一下: 一个图的配置 在echarts官网demo界面 option {title: {text: },legend: {data: [xxx前, xxx后]},radar: {// shape: circle,name: {// 雷达图各类别名称文本颜色textStyle: {color: #000,fontSize: 16}},indicator: [{ name: 完整性, max: 1 },{ name:…

ByteBuffer调试工具类

一个可以形象展示ByteBuffer内容的方法,便于调试 package com.example.netty;import java.nio.ByteBuffer;public class ByteBufferUtil {/*** 打印ByteBuffer的内容,以十六进制和ASCII字符的形式展示。** param buffer 要展示的ByteBuffer*/public sta…