[网络编程]TCP和UDP的比较 及 通过java用UDP实现网络编程

news2024/11/15 8:01:09

文章目录

  • 一. 网络编程套接字
  • TCP和UDP的特点
    • 有连接 vs 无连接
    • 可靠传输 vs 不可靠传输
    • 面向字节流 vs 面向数据报
    • 全双工 vs 半双工
  • 二. java用UDP实现网络编程
    • 代码实现:
    • 运行代码:
    • 启动多个客户端
    • 别人能否使用?
    • 实现翻译功能

一. 网络编程套接字

网络编程套接字, 就是指操作系统提供的网络编程的api, 称为"socket api"

操作系统, 提供的socket api, 有三套:

  1. 流式 套接字 => 给TCP使用的
  2. 数据报 套接字 => 给UDP使用的
  3. Unix域套接字 =>不能夸主机通信, 只能本地主机上的进程和进程之间的通信(现在很少使用)

TCP和UDP都是传输层协议, 都是给应用程序提供服务的
但是这两个协议特点差异非常大, 因此我们就需要搞两套api, 来分别表示

TCP和UDP的特点

TCP的特点:
有连接, 可靠传输, 面相字节流, 全双工
UDP的特点:
无连接, 不可靠传输, 面向数据报, 全双工

有连接 vs 无连接

计算机中的连接, 指的是建立联系的双方, 各自保存对方的信息
那么TCP协议要求:
通信双方保存对方的信息
UDP要求:
通信双方不需要保存对方的信息

可靠传输 vs 不可靠传输

可靠 != 安全
可靠, 指的是要传输的数据, 尽可能的传输给对方, 尽力不是确保
那么, TCP协议, 内部提供了一系列的机制, 来实现可靠传输
UDP协议, 只关心发送, 并不关心后续

面向字节流 vs 面向数据报

文件操作, 也是字节流的, 读写非常灵活, 读写的基本单位就是字节
TCP也是字节流的

数据报Datagram, 数据段Segment, 数据包Packet, 数据帧Frame, 这些都是网络传输数据的基本单位, 但是有不同的使用场景
那么, UDP, 是面向数据报, 传输数据的基本单位, 是一个个的UDP数据报

全双工 vs 半双工

全双工: 一条链路, 能够进行双向通信
半双工: 一条链路, 只能进行单向通信
TCP, UDP都是全双工

后续会对TCP和UDP进行进一步详细介绍

二. java用UDP实现网络编程

socket api 都是系统提供的, java中对于系统的这些api进行进一步封装了
UDP的socket api 重点的两个类:
1. DatagramSocket
系统中的socket, 可以理解成是一种"文件", socket文件, 可以视为是"网卡"这种硬件设备的抽象表现形式
DatagramSocket, 就是对socket进行封装, 可以视为是"操作网卡"的遥控器
针对这个对象进行读写操作, 就是在针对网卡进行读写操作

具有"遥控器属性"这样的概念, 计算机中起了个专门的名字"句柄"(handle)

构造方法:
在这里插入图片描述
读写方法:
在这里插入图片描述

2. DatagramPacket
是针对UDP数据报的一个抽象表示

构造方法:
在这里插入图片描述
成员方法:
在这里插入图片描述

代码实现:

网络程序, 既有服务器, 也有客户端
我们现在只是进行一个简单的实现, 服务器收到客户端请求后, 无需做什么, 客户端请求啥, 直接响应啥, 这种程序, 就叫做"回显"(Echo)
服务器:
第一步:创建对象
在这里插入图片描述

  1. 服务器运行, 要把端口号确定下来, 以便让客户端找到, 客户端才能主动发送请求
    实际运行的时候, 端口只能为多少是程序猿自己决定的
    但是要确保: 1)端口号是合法的 1-65535 2) 自己写的端口号, 不能和别的进程使用的端口号冲突
  2. 为什么把new对象放在构造方法里? 方便抛异常

第二步:创建start方法
在这里插入图片描述
服务器需要不停的处理请求, 不停地响应, 所以需要写成死循环

第三步:读取请求并解析
在这里插入图片描述
这个对象是一个UDP数据报, 包含两个部分:
1)报头(通过类的属性来表示的)
2)载荷(通过构造方法传递的字节数组, 作为持有载荷的空间, 这个存储载荷的空间, 人家没有自己new, 而是让你new好)

在这里插入图片描述
如果receive没有收到请求, 那么就会阻塞等待, 直到有客户端发送请求
为了方便后续再java代码中的处理(打印), 可以把上述数据报中的二进制数据拿出来, 构造成String

第四步:根据请求计算响应
在这里插入图片描述
将响应的结果通过process方法返回:
在这里插入图片描述

第五步: 把响应写回到客户端
在这里插入图片描述
构造一个DatagramPacket作为发送的数据报
第一个参数是byte[] 类型, String中的getBytes()方法可以获取字节
最后一个参数是用来获取客户端的ip和端口信息

前面我们知道, UDP是无连接的, 所以本身并没有存储对方的ip和端口信息, 但是上述我们用来接收数据的DatagramPacket中, 存放了客户端的ip和接口, 所以我们可以通过getSocketAddress()方法来获取到

第六步: 打印请求记录
在这里插入图片描述
这样我们就完成了UDP协议下的服务器实现!

完整代码:

public class UDPEchoServer {
    private DatagramSocket socket = null;

    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], 4096);
            socket.receive(requestPacket);
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            //2)根据请求计算响应
            String response = this.process(request);
            //3)把响应写回到客户端
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), 0, response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);

            System.out.printf("[%s:%d] req=%s, resp=%s\n", requestPacket.getAddress(), requestPacket.getPort(),
                    request, response);
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UDPEchoServer server = new UDPEchoServer(9090);//随便假设的端口号, 如果不能运行就换一个
        server.start();
    }

}

客户端:
第一步:创建对象
因为客户端是先发送请求的一端, 所以当我们创建类的时候, 需要知道服务器的ip地址和端口
在这里插入图片描述
注意: 客户端这边, 创建DatagramSocket对象时, 不需要传端口参数
不是客户端不需要端口, 是因为操作系统, 自动分配了一个空闲的(不和别人冲突)的端口号, 不需要自己指定
这个自动分配的端口号, 每次重新启动程序都可能不一样

第二步: 创建start方法
在这里插入图片描述
客户端可以不停地给服务器发送请求, 所以使用死循环

第三步: 从控制台读取用户输入
在这里插入图片描述

第四步: 构造请求并发送
在这里插入图片描述
因为客户端和服务器之间是没有连接的, 所以我们怎么才能知道将数据传给谁呢
数据报帮我们完成了这个工作, 在构造数据报时, 我们需要传5个参数,
前三个和写服务器是一样, 将字符串转化成字节数组, 并规定长度
后两个是传服务器的IP地址和端口号
传服务器的IP地址时, 我们所获取到的是点分十进制的字符串, 我们需要转化成java能够识别的对象
需要借助InetAddress.getByName方法

第五步: 读取响应的数据
在这里插入图片描述
需要自己new空间存放数据

第六步:显示响应到控制台
在这里插入图片描述
将接收到的数据报转成字符串, 打印到控制台上

第七步: 实现main方法
在这里插入图片描述
当前服务器和客户端在一个主机上, 固定使用"127.0.0.1" 这个ip即可, 称为环回ip

完整代码:

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp;
    private int serverPort;

    public UdpEchoClient(String serverIp, int serverPort) throws SocketException {
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }

    public void start() throws IOException {
        System.out.println("客户端启动!");
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.println("请输入要发送的请求");
            //1. 从控制台读取用户输入
            String request = scanner.next();
            //2. 构造请求并发送
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),0,request.getBytes().length,
                    InetAddress.getByName(serverIp), serverPort);
            socket.send(requestPacket);
            //3. 读取响应的数据
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            //4. 显示响应到数据台
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            System.out.println(response);
        }
    }

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

运行代码:

要先运行服务器, 再运行客户端
在这里插入图片描述
在这里插入图片描述
这样, 客户端和服务器就能够正常运行啦

启动多个客户端

默认情况下, idea里面只能启动一个客户端, 要想启动多个:
在这里插入图片描述
在这里插入图片描述
这样就可以运行多个客户端啦
在这里插入图片描述
在这里插入图片描述

别人能否使用?

我们这个客户端和服务器都在同一个主机上, 那么不同如果是不同主机, 是不能成功的
因为:
我们的电脑的IP只是一个局域网内部使用的私有IP, 而不是在广域网上直接使用的"公有IP"
虽然我们没有公有IP, 但是我们可以买云服务器

实现翻译功能

在这里插入图片描述
我们上述逻辑, 属于回显, 并没有实际完成什么逻辑
接下来我们来实现一个简单的翻译功能的服务器
由于逻辑大致相同, 只有process内部的功能不同, 所以我们可以使用继承来完成

 public class UdpDictServer extends UDPEchoServer{
    private Map<String, String> dict = null;

    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict = new HashMap<>();
        dict.put("hello", "你好");
        dict.put("cat", "小猫");
        dict.put("dog", "小狗");
    }

    @Override
    public String process(String request) {
        return dict.getOrDefault(request, "没查询到该词汇");
    }

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

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

linux 部署Ollama本地大模型

简介 llama 是一个大模型的管理框架&#xff0c;其作用类似于 Docker&#xff1a;如果将每一个标准化的大模型视为“镜像”&#xff0c;那么 Ollama 就能够通过一行命令快速拉取并运行这些大模型。然而&#xff0c;Ollama 本身是基于命令行的服务&#xff0c;所以为了方便我们…

足底筋膜炎怎么治

足底筋膜炎是一种常见的足部疾病&#xff0c;其主要症状及治疗方法如下&#xff1a; 一、症状 1、‌疼痛‌&#xff1a;足底筋膜炎最典型的症状是足跟或足底靠近足跟处的疼痛。这种疼痛在晨起或长时间休息后初次站立时尤为明显&#xff0c;但行走一段时间后可能会逐渐缓解。 …

超级兔子and这三款数据恢复软件,我的数据守护神!!

在数字化的时代&#xff0c;数据丢失已经成为了一个令人头疼的问题。无论是误删重要文件&#xff0c;还是硬盘出现故障&#xff0c;数据的丢失都可能带来不可估量的损失&#xff1b;幸运的是&#xff0c;有了超级兔子这这三款数据恢复软件这样的工具&#xff0c;让数据找回变得…

AI基础 L1 Introduction to Artificial Intelligence

什么是AI Chinese Room Thought Experiment 关于“强人工智能”的观点&#xff0c;即认为只要一个系统在行为上表现得像有意识&#xff0c;那么它就真的具有理解能力。 实验内容如下&#xff1a; 假设有一个不懂中文的英语说话者被关在一个房间里。房间里有一本用英文写的中…

【C++】list类:模拟实现(适合新手的手撕list)

提示&#xff1a;在开始模拟实现list前&#xff0c;最好先熟悉下list相关接口&#xff1a; 【C】容器list常用接口详解-CSDN博客https://blog.csdn.net/2301_80555259/article/details/141756824?spm1001.2014.3001.5501 目录 一.基本结构 二.构造函数 三.析构函数 四.迭代…

拍卖新纪元:Spring Boot赋能在线拍卖解决方案

需求分析 1.1技术可行性&#xff1a;技术背景 在线拍卖系统是在Windows操作系统中进行开发运用的&#xff0c;而且目前PC机的各项性能已经可以胜任普通网站的web服务器。系统开发所使用的技术也都是自身所具有的&#xff0c;也是当下广泛应用的技术之一。 系统的开发环境和配置…

ant mobile design组件库的PickerView组件不能滑动

问题 PickerView组件在开发环境可滑动&#xff0c;在测试环境不可滑动 正常开发环境是这样正常显示&#xff0c;并且可滑动的 发到测试环境后&#xff0c;变成了这样&#xff0c;并且只有中间那列可滑动&#xff0c;两边的都不能滑动&#xff0c;而且还会报警告 封装的组件…

修改服务器DNS解析及修改自动对时时区

修改服务器DNS解析&#xff1a; 1、搜索一下当地的DNS服务器的地址 2、登录服务器&#xff0c;执行 vim /etc/resolv.conf文件&#xff0c;在nameserver字段后填写DNS服务的地址 3、chattr i /etc/resolv.conf 加上不可修改权限&#xff0c;防止重启DNS被修改 修改自动对时…

jmeter压力测试,通过LLM利用RAG实现知识库问答,NEO4J部署,GraphRAG以知识图谱在查询时增强提示实现更准确的知识库问答(9/7)

前言 这周也是杂七杂八的一天&#xff08;高情商&#xff1a;我是一块砖&#xff0c;哪里需要往哪里搬&#xff09;&#xff0c;首先是接触了jemter这个压力测试工具&#xff0c;然后帮公司的AIGC项目编写使用手册和问答手册的第一版&#xff0c;并通过这个平台的智能体实现知识…

【LabVIEW学习篇 - 16】:文件操作

文章目录 CSV文件CSV写入CSV读取 TXT文件txt写入txt读取 INI文件INI文件写入INI文件读取 CSV文件 .csv (Comma-Separated Values&#xff09;是逗号分隔值文件格式&#xff0c;有时也称之为字符分隔值&#xff0c;因为分隔符也可以不是逗号(最常见的是逗号和制表符)&#xff0…

Spring01——Spring简介、Spring Framework架构、Spring核心概念、IOC入门案例、DI入门案例

为什么要学 spring技术是JavaEE开发必备技能&#xff0c;企业开发技术选型命中率>90%专业角度 简化开发&#xff1a;降低企业开发的复杂度框架整合&#xff1a;高效整合其他技术&#xff0c;提高开发与运行效率 学什么 简化开发 IOCAOP 事务处理 框架整合 MyBatis 怎…

mybatis特殊符号处理,mybatis一级二级缓存,java反射机制

mybatis特殊符号处理 在 mybatis 中的 xml 文件中&#xff0c;存在一些特殊的符号&#xff0c;比如&#xff1a;<、>、"、&、<>等&#xff0c;正常书写 mybatis 会报错&#xff0c;需要对这些符号进行转义。具体转义如下所示&#xff1a; 特殊字符 转义字…

Openharmony软件评估指南-米尔瑞芯微RK3568开发板

Openharmony软件评估指南用于介绍在米尔的开发板上运行Openharmony系统下的核心资源与外设资源的测试步骤与评估方法。本文可作为前期评估指南使用&#xff0c;也可以作为通用系统开发的测试指导书使用。 本文档使用于米尔电子的MYD-LR3568系列板卡&#xff0c;该板卡是米尔电…

HCIE云计算--灾备

7、BCManager ebackup–云场景备份管理软件 8、ebackup软件的组成 9、ebackup的部署方式 10、ebackup的网络平面 11、组网方式 12、CBT技术–实现增量备份、差异备份、增量恢复 13、CBT和快照对比技术CBT 灾备释义&#xff1a;指利用科学的技术手段和方法&#xff0c;提前…

【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染

【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染 一、环境说明二、调用后台接口及List组件渲染三、总结 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、调用后台接口及List组件渲染 后台接口及返回数据分析 JSON数据格式如下&#xf…

2024最新技术!使用Golang Beego开发的社区老人健康管理系统,Vue前端交互流畅,大数据分析助力健康趋势预测

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

用PG Back Web轻松进行PostgreSQL备份

什么是 PG Back Web &#xff1f; PG Back Web &#x1f418; 使用用户友好的 Web 界面轻松进行 PostgreSQL 备份&#xff01;&#x1f310;&#x1f4be;。PG Back Web 不仅仅是另一个备份工具。借助 PG Back Web&#xff0c;用户可以通过受 PGP 加密保护的直观 Web 界面轻松安…

JAVA—网络通信

本文是学习网络通信入门和简单了解UDP协议和TCP协议&#xff0c;学习和了解CS架构和简单了解BS架构和HTTP协议&#xff08;部分图片来自黑马程序员&#xff09; 目录 1.网络通信三要素 &#xff08;1&#xff09;IP地址 &#xff08;2&#xff09;端口号 &#xff08;3&am…

RHCE必过技巧,无需本人参加也可拿证?

RHCE(无需本人参加&#xff0c;给信息给款即可拿证) ​培训&#xff0b;认证 ​月初一期 ​月尾一期

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测+交叉验证

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证 目录 回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现基于贝叶…