Java网络编程,使用UDP实现TCP(二), 实现数据传输过程

简介:

经过了三次握手过程,我们的服务端和客户端已经建立了连接。我们接下来需要做的就是数据的传输。

主要步骤:

  1. 数据发送:客户端或服务器将数据打包成一个或多个数据段,每个数据段都有一个序列号(SEQ)和确认号(ACK)。

  2. 数据接收:接收方接收到数据段后,将根据数据段的序列号(SEQ)进行排序,以确保数据的有序性。

  3. 确认接收:接收方会为每个接收到的数据段发送一个确认(ACK)。这个确认包含了确认号(ACK),该确认号是接收方期望接收的下一个数据段的序列号,也就是最后一个接收到的数据段的序列号加1。

  4. 丢包重传:如果发送方在一定时间内没有接收到某个数据段的确认,它会认为该数据段已经丢失,并进行重传。

  5. 流量控制:接收方可以使用窗口大小字段来控制发送方的发送速度,以防止自己被大量的数据淹没。

  6. 拥塞控制:如果网络发生拥塞,TCP会降低数据的发送速度,以减少网络的拥塞程度。(未实现)

所以在数据传输段过程中,每一段都需要Seq(序列号),ACK(确认号)

实现过程:

  1. 确认号(ACK)是基于之前接收到的最后一个数据包的序列号+1。也就是说,ACK的值是接收方期望接收的下一个数据包的序列号。这是因为,在TCP协议中,ACK的值总是等于接收方已经成功接收的最后一个数据包的序列号+1。
  2. 例如,假设在三次握手的过程中,客户端发送给服务器的最后一个ACK是101(这是第三次握手的ACK),那么在数据传输开始时,如果服务器是第一个发送数据的话,服务器发送的第一个数据包的序列号应该是101,而客户端回复的ACK就应该是102,表示客户端已经接收到了序列号为101的数据包,期望接收的下一个数据包的序列号是102。

服务端发送数据到客户端

  • 注意由于数据的传输是双向的,所以在发送后可以接收客户端发来的数据。
  • 在接收数据后,我们在服务端需要进行超时判断,如若超时会进行超时重传。超时判断我们使用了 setSoTimeout() 方法。
    • 关于超时的时间,根据《TCP/IP详解》卷二 的计时器篇中可知,超时时间严苛来说,需要考虑发送端到接收端接收数据时间接收端数据处理时间接收端发送确认消息到客服端时间。超时时间的选择应该是多次数据传输花费时间的均值
  • 在《TCP/IP详解》卷二 的 tcp 篇详细中规定了数据重传不能超过三次,这里我使用了retryCount这个计数器来计数。
//数据传输开始System.out.println("====================");System.out.println("数据发送...");String SeqD1 = String.valueOf(connectionMarks.getSeq());String ACKD1 = String.valueOf(Integer.parseInt(strArr3[1]) + 1);String dataMsg = SeqD1 + " " + "我是马尔咖里斯,我是不朽的!" + " " + ACKD1;byte[] datasD1 = dataMsg.getBytes();DatagramPacket datagramPacketD1 = new DatagramPacket(datasD1, 0,datasD1.length, new InetSocketAddress("localhost",8888));int maxRetries = 3; // 最大重试次数int retryCount = 0; // 当前重试次数boolean success = false; // 是否成功标志while (!success && retryCount < maxRetries) {try {// 设置超时时间datagramSocket.setSoTimeout(50000);// 发送数据datagramSocket.send(datagramPacket);// 接收响应byte[] buffer = new byte[1024];DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length);datagramSocket.receive(responsePacket);// 处理响应String response = new String(responsePacket.getData(), 0, responsePacket.getLength());System.out.println("接收到响应:" + response);// 设置成功标志success = true;} catch (java.net.SocketTimeoutException e) {// 超时后重新发送数据retryCount++;System.out.println("超时,进行第 " + retryCount + " 次重试");} catch (IOException e) {// 处理其他异常e.printStackTrace();}}if (!success) {System.out.println("重试次数超过最大限制,操作失败");}

客户端发送数据到服务端

注意:在tcp三次握手后数据段的传输也需要添加ACK,和Seq,如前文所述。这里为了便于实现在传回数据时只写了数据返回 “收到消息” 是不符合规定的,需要修改。

 System.out.println("====================");System.out.println("开始接收数据段...");byte[] bytes1 = new byte[1024];DatagramPacket datagramPacketD1 = new DatagramPacket(bytes1, bytes1.length);datagramSocket.receive(datagramPacketD1);String receiveMsg = new String(datagramPacketD1.getData(), 0, datagramPacketD1.getLength());System.out.println("接收到的数据段为:" + receiveMsg);String[] split = receiveMsg.split(" ");String SeqD1 = split[0];System.out.println("====================");System.out.println("数据消息确认返回");String replyMsg = "收到消息";clientMsg.sendMsg(replyMsg, datagramSocket);

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

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

相关文章

mybatis xml 热部署

平时我们在项目中多多少少会根据不同的情况等等原因去调试sql&#xff0c;在数据库测试完后也需要在代码里面运行测试&#xff0c;但是每次修改就需要重启服务就显得太繁琐&#xff0c;所以如果mybatis的xml也可以热部署当然是最好的了&#xff0c;那我来试试如何可以将mybatis…

pytorch-0.4.0上古版本安装参考

由于pytorch previous-versions中已经不显示该版本&#xff0c;而且网络上信息很少&#xff0c;配环境给我配麻了&#xff0c;所以提供一个参考。 我的配置&#xff1a; cuda 9.0 gcc 4.8.5 安装过程&#xff1a; conda create -n torch040 python3.6.6 conda install pytorc…

C++ 学习系列 -- conversion function

一 什么是转换函数&#xff1f; 在 c 编码中&#xff0c;我们可能遇到要将类 A 转为 类 B 的情况&#xff0c;此时就可以定义类 A 的转换函数将其按照一定规则转换为 类 B&#xff1b; 转换函数声明规则如下&#xff1a; operator 转换类型() const; 转换函数无返回值&#x…

基于chaos混沌的彩色图像加解密系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 混沌理论简介 4.2 基于混沌的图像加密原理 4.3 数学公式与实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .................…

记录将C语言编写的Windows程序转换为python语言编写,演示具体效果在最后,这对初学者理解Windows消息机制及框架有一定参考作用

主要思路 由于C语言的数组定义使用名字加中括号及括号内数字定义&#xff0c;但是在python中【】已经被作为列表 元组等序列类型分片、存取元素&#xff0c;因此我们不能像C语言那样定义数组 例如C语言 int a[10] 是声明定义一个含有10个int类型的数组a,而在执行语句部分…

Android基础:使用Intent意图类 和 Bundle类对安卓页面Activity页面进行数据的传递 实现Activity页面之间通信技术

Android Intent 和 Bundle与Activity之间的通信 下面是Android基础&#xff1a;使用Intent意图类 和 Bundle类对安卓页面Activity页面进行数据的传递 && 实现Activity页面之间通信技术 ** 实现的目的 **&#xff1a;页面之间的数据传输&#xff0c;通过将数据打包传递…

华为OD机试真题B卷 Java 实现【统计大写字母个数】,附详细解题思路

一、题目描述 找出给定字符串中大写字符(即’A’-‘Z’)的个数。 数据范围&#xff1a;字符串长度&#xff1a;1≤∣s∣≤250 字符串中可能包含空格或其他字符 二、输入描述 对于每组样例&#xff0c;输入一行&#xff0c;代表待统计的字符串。 三、输出描述 输出一个整…

【1day】​万户协同办公平台 iSignatureHTML.jsp/DocumentEdit.jsp 文件SQL注入漏洞学习

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现

【css】css实现文字两端对齐效果:

文章目录 一、方法1&#xff1a;二、方法2&#xff1a;三、注意&#xff1a; 一、方法1&#xff1a; 给元素设置 text-align: justify;text-align-last: justify;并且加上text-justify: distribute-all-line; 目的是兼容ie浏览器 p{width: 130px;text-align: justify;text-alig…

飞天使-linux操作的一些技巧与知识点3-http的工作原理

文章目录 http工作原理nginx的正向代理和反向代理的区别一个小技巧dig 命令巧用 http工作原理 http1.0 协议 使用的是短连接&#xff0c;建立一次tcp连接&#xff0c;发起一次http的请求&#xff0c;结束&#xff0c;tcp断开 http1.1 协议使用的是长连接&#xff0c;建立一次tc…

Network 灰鸽宝典【目录】

目前已有文章 21 篇 Network 灰鸽宝典专栏主要关注服务器的配置&#xff0c;前后端开发环境的配置&#xff0c;编辑器的配置&#xff0c;网络服务的配置&#xff0c;网络命令的应用与配置&#xff0c;windows常见问题的解决等。 文章目录 服务配置环境部署GitNPM 浏览器编辑器系…

GEE:重分类

作者:CSDN @ _养乐多_ 本文记录了在 Google Earth Engine(GEE)平台上对一副类别图像进行重分类的代码。并以 COPERNICUS/Landcover/100m/Proba-V-C3/Global 数据集中的土地利用数据为例。 结果如下图所示, 文章目录 一、核心函数二、示例代码三、代码链接一、核心函数 核…

文件操作及函数

什么是文件&#xff1f; 在程序设计中&#xff0c;文件有两种&#xff1a;程序文件和数据文件。 程序文件 包括源程序文件&#xff08;.c&#xff09;&#xff0c;目标文件&#xff08;.obj&#xff09;&#xff0c;可执行程序(.exe)。 数据文件 文件的内容不一定是程序&…

linux下部署frp客户端服务端-内网穿透

简介 部署在公司内部局域网虚拟机上的服务需要在外网能够访问到&#xff0c;这不就是内网穿透的需求吗&#xff0c;之前通过路由器实现过&#xff0c;现在公司这块路由器不具备这个功能了&#xff0c;目前市面上一些主流的内网穿透工具有&#xff1a;Ngrok&#xff0c;Natapp&…

Docker镜像构建:深入Dockerfile创建自定义镜像

Docker的强大之处在于其能够通过Dockerfile定义和构建自定义镜像&#xff0c;为应用提供独立、可移植的运行环境。在这篇博客文章中&#xff0c;将深入探讨Docker镜像构建的核心概念&#xff0c;通过更加丰富的示例代码&#xff0c;帮助大家全面理解和掌握构建自定义镜像的技术…

深度学习在人体动作识别领域的应用:开源工具、数据集资源及趋动云GPU算力不可或缺

人体动作识别检测是一种通过使用计算机视觉和深度学习技术&#xff0c;对人体姿态和动作进行实时监测和分析的技术。该技术旨在从图像或视频中提取有关人体姿态、动作和行为的信息&#xff0c;以便更深入地识别和理解人的活动。 人体动作识别检测的基本步骤包括&#xff1a; 数…

关于MySQL的bigint问题

MySQL的bigint(8)能存多大数值&#xff1f; MySQL的BIGINT(8)可以存储的数值范围是从-9,223,372,036,854,775,808到9,223,372,036,854,775,807。这是因为BIGINT数据类型在MySQL中使用8字节进行存储&#xff0c;每个字节有8位&#xff0c;所以总共可以表示2^64个不同的整数。 …

IDEA 出现问题:git提交commit时Perform code analysis卡住解决方案

问题 git提交commit时Perform code analysis卡住很久 解决方案一 1、打开 IntelliJ IDEA&#xff0c;进入 File -> Settings&#xff08;或者使用快捷键 CtrlAltS&#xff09;。 2、在弹出的 Settings 窗口中&#xff0c;找到 Version Control -> Commit Dialog 选项…

什么是数字化营销?如何进行数字化营销?数字化有多重要?

引言 数字化营销是一种利用数字技术和在线平台来促进产品或服务销售的策略。它包括利用各种数字渠道&#xff0c;如社交媒体、搜索引擎优化、内容营销和数据分析等&#xff0c;与目标受众建立联系并推动销售。 在当今商业环境中&#xff0c;数字化营销扮演着至关重要的角色。…

阿里云国际版无法远程连接Windows服务器的排查方法

如果您遇到紧急情况&#xff0c;需要尽快登录Windows实例&#xff0c;请参见以下操作步骤&#xff0c;先检查ECS实例的状态&#xff0c;然后通过云助手向Windows实例发送命令或通过VNC登录实例&#xff0c;具体步骤如下&#xff1a; 步骤一&#xff1a;检查ECS实例状态 无论何…