java-网络编程-大文件极限传输

简介: 代码:https://github.com/jinhang/OkFileTransfer/blob/master/README.md背景阿里搬砖头比赛说好是Client端线程级的同步阻塞请求,结果一帮人用了协程来完成这件事。

代码:

https://github.com/jinhang/OkFileTransfer/blob/master/README.md

背景

阿里搬砖头比赛说好是Client端线程级的同步阻塞请求,结果一帮人用了协程来完成这件事。其实吧,我想说就算用协程来完成,其实本质也和异步差不多(就网络通讯层),不过却激发了我的好奇心,因为比赛的结果是1G极限,只用了3秒!

3秒…如果我们将题目往对我有利的思考方向改变下,不再是Client端线程级的同步阻塞,只要求Server端请求应答同步即可。即:Server端在没收到一个请求之前,不能提前将下一个应答发出!如果我将题目修改为这样,我也不见得非常有信心能将时间控制在3秒以内!

所以这里立了个小项目来验证不同的实现方式下,对网络传输、CPU使用的开销。项目起名为镭射,取汇集小请求将能量集中爆发之意。

打算挑战下极限搬运的。

思路参考

穿越nat传输完整的文件,而且能自动重传丢失报文,采用UDP协议,在跨大洲之间进行完整的大文件(超过2GB)传输。
主要解决思路和技术点如下:
对每个报文进行文件任务标志。可以同时传输多个文件。
发送文件内容之前,先发送文件名。然后返回文件名收到后的确认,然后再开始传输。
对发送报文进行计数,每隔1000个报文(某个时间间隔),接收端发送一个计数报文,报告丢包率。采取降低发送速度等措施。
长期丢包率在99%以上,尝试提高发送速度一倍。如果丢包率超过10%就降速。
文件传输中断,有中断信息。接收端长期没有接受到文件报文,则终止任务。
发送完毕后,接收端发送完毕报文,结束发送。
10000个报文组成一个块的概念,接收端每收到10000个(某个数字)报文,发送接受块成功的消息。整个块不会重复发送。如果块出现某个报文发送失败,则重新发送报文。
每个UDP报文,大小是1464字节,其中64个字节用来标示任务。
采用java编写,在web端使用,在tomcat启动时,也就是servlet的contextlistener启动的时候,启动守护进程,监听udp的80端口。是否与servlet进行协同。为了支持子网,客户端只负责发送和上传数据,不能下载数据。所以计数和控制,可能需要tcp的参与。

首先是报文,为了降低开发工作量。
先使用udp报文的48个字节。剩下24个还没想好。
首先将48个字节分为6个long类型。
第一个long,标识版本和报文类型。
比如1表示是数据传输
2表示是重传通知等等。
第二个long,是uuid的high位
第三个long,是uuid的low位。
一起标识一个文件。
第四个long是包序号。
第五个long是包内报文序号
第六个long是下面的报文长度。
第七个long是在被传输文件里面的位移量
第八个long是在传输文件里面的写入长度

开始为了测试方便,将udp报文的数据长度设为1024,总长度是1024+64=1088
将缓冲窗口设为512KB,即在内存开辟一个512KB的缓冲器,当收满512个UDP报文时,写内存中的数据写入目标文件。如果512个报文在单位时间内,没有收满,说明有丢包,则选择丢失的报文重传。丢包判断待定。在UDT协议里面是采用等待4倍的RTT时间判断的,在4倍的RTT时间后未到达的报文都被判断为丢失。
目前完成了udp的服务启动。数据传输窗口的相关开发。其实只要保证窗口内的512KB数据传输成功即可。每512KB作为一个window,然后返回确认信息。客户端确认接到512KB完成的确认信息后,再去发送下一个512KB。确认信息里面可以加入crc校验或者MD5校验。客户端判断一下是否正确,决定是否重传。如果客户端决定,继续发送,则直接发送报文即可。服务器端,接到新的报文,如果是新报文ID,则将旧512KB数据写入实体文件,然后更新window,将收到的第一个报文写入window的相应位置。如果客户端没有收到服务器端的window结束的确认报文,则等待,而不发送新的报文。服务器端等待4个RTT时间,再发送确认报文,最多重试5次。如果5次客户端都没收到确认报文,不发送新数据,服务器没有接受新数据,则服务器端认为网络中断。停止任务。将任务写入临时文件。等待客户端下一次重传唤醒。刚才浏览下网页又有新的收获:估计这个程序的上传客户端可以直接拿javascript来写了。比较理想了。之前的思路有点问题,关于客户端停止发送这一点,会导致传输效率变低,应该是客户端继续发送,直到5个RTT时间后,没有收到上个window结束信号之后,再停止发送。
UDP之所以比TCP效率高,本质原因是TCP的一个bug,TCP将RTT时间和带宽联系在一起,片面认为RTT时间越长,带宽越低,而真实情况是,RTT和带宽没有直接关系。

目录
相关文章
|
2月前
|
JSON 移动开发 网络协议
Java网络编程:Socket通信与HTTP客户端
本文全面讲解Java网络编程,涵盖TCP与UDP协议区别、Socket编程、HTTP客户端开发及实战案例,助你掌握实时通信、文件传输、聊天应用等场景,附性能优化与面试高频问题解析。
|
5天前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
39 1
|
5天前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
72 1
|
5天前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
36 1
|
8天前
|
机器学习/深度学习 分布式计算 Java
Java与图神经网络:构建企业级知识图谱与智能推理系统
图神经网络(GNN)作为处理非欧几里得数据的前沿技术,正成为企业知识管理和智能推理的核心引擎。本文深入探讨如何在Java生态中构建基于GNN的知识图谱系统,涵盖从图数据建模、GNN模型集成、分布式图计算到实时推理的全流程。通过具体的代码实现和架构设计,展示如何将先进的图神经网络技术融入传统Java企业应用,为构建下一代智能决策系统提供完整解决方案。
109 0
|
1月前
|
运维 架构师 安全
二层协议透明传输:让跨域二层协议“无感穿越”多服务商网络
简介:本文详解二层协议透明传输技术,适用于企业网工、运营商及架构师,解决LLDP/LACP/BPDU跨运营商传输难题,实现端到端协议透传,提升网络韧性与运维效率。
|
3月前
|
监控 Java API
Java语言按文件创建日期排序及获取最新文件的技术
这段代码实现了文件创建时间的读取、文件列表的获取与排序以及获取最新文件的需求。它具备良好的效率和可读性,对于绝大多数处理文件属性相关的需求来说足够健壮。在实际应用中,根据具体情况,可能还需要进一步处理如访问权限不足、文件系统不支持某些属性等边界情况。
217 14
|
3月前
|
存储 Java 编译器
深入理解Java虚拟机--类文件结构
本内容介绍了Java虚拟机与Class文件的关系及其内部结构。Class文件是一种与语言无关的二进制格式,包含JVM指令集、符号表等信息。无论使用何种语言,只要能生成符合规范的Class文件,即可在JVM上运行。文章详细解析了Class文件的组成,包括魔数、版本号、常量池、访问标志、类索引、字段表、方法表和属性表等,并说明其在Java编译与运行过程中的作用。
|
3月前
|
存储 人工智能 Java
java之通过Http下载文件
本文介绍了使用Java实现通过文件链接下载文件到本地的方法,主要涉及URL、HttpURLConnection及输入输出流的操作。
206 0
|
4月前
|
存储 Java 数据安全/隐私保护
Java技术栈揭秘:Base64加密和解密文件的实战案例
以上就是我们今天关于Java实现Base64编码和解码的实战案例介绍。希望能对你有所帮助。还有更多知识等待你去探索和学习,让我们一同努力,继续前行!
353 5