Java 使用 TCP 和 UDP 传输文件

简介:
 引言
  本项目的目的是实现两个应用,通过网络连接在不同的主机之间传输一个文件的功能。两个应用应该分别利用 UDP 和 TCP 协议,以具有传输至少 1 MB 文件的能力。
   实现和说明
  源代码
  两个应用都由单个程序实现,源代码下载地址。
   说明
  程序使用以下命令行进行编译:
  javac *.java
  然后使用以下两个命令行运行:
Receiver:
java FileReceiver [protocol] [port]
Sender:
# java FileSender [protocol] [host] [port] [filename]
  其中 [protocol] 参数可以是 "udp" 或者 "tcp",但 sender 和 receiver 必须一致。
  文件将会在 receiver 启动的目录下生成,默认指定名为 "Received-[filename]"。
   TCP 实现
  实现概述
  在 TCP 实现中,Receiver 打开了一个 ServerSocket,并对定义好的端口进行监听。Sender 启动后将会为监听者 Receiver 打开一个新的 Socket,这导致了 socket 两端 InputStream 和 OutputStream 对象的创建。
  一个包含了文件名和文件大小的初始信息将由 Sender 发送给 Receiver。这样 Receiver 可以使用一个有意义的名字来存储接收到的文件,并可以判断什么时候文件完全传输完毕。此信息并不是必须的,当 Receiver 无法接收文件时停止 Sender 占用不必要的带宽。
  文件通过一个 FileInputstream 对象对它的读取进行传输,然后将数据写到一个 Socket 返回的 OutputStream 对象。为提高应用效率,每次读取和中继的数据是 8 kb,使用一个字节数组作为缓存。
  TCP 使用经验
  实践证明,TCP 文件传输是简单可靠的。程序的效率取决于使用的缓存大小,但传输的文件在所有执行的 测试中都准确地被接收和保存。
   UDP 实现
  实现概述
  UDP 文件传输的实现使用的是标准 Java datagram 类:DatagramPacket 和 DatagramSocket。
  当 receiver 被执行时,它打开一个指定端口号的 socket 并等待,监听传入的数据包。sender 启动后,它打开一个连接到指定主机和端口的 socket,并传输包含有文件名以及将要传输文件大小等信息的单个 packet。当这个 package  发送以后,这个 socket 将等待并监听 package。
  基于接收到的初始 package,receiver 为文件创建一 outputStream 对象,并给监听着的 sender 发送一个含有 "OK" 单词的 package。收到这个 "OK" 包以后,sender 开始读取文件内容,并将其通过 UDP 数据包发送,每次含有 512 字节的块。receiver 将这些块按照接收到的次序写入文件,并重复接收,直到接收到的字节达到它所期望数字。之后程序终止。
   UDP 使用经验
  UDP 是一种不可靠的传输连续数据的协议。这意味着传输过程中会有丢包,而且接收到包的次序也是随机的。上面的例子并没有解决文件传输中的这些问题。这意味着以上应用在其每次运行时(所得到的文件)并不是正确的和完整的。以下是关于两个经常发生的问题的原因以及可行解决方案的描述。
  如果在文件传输过程中两个包接收顺序错误,而写入文件的顺序是按接收顺序来的。这将造成接收文件损坏。对于这种问题的解决方案是每次传输时定义一个序列号。这可以让 Receiver 按照正确的顺序来存储这些包,不管它们到达的先后次序。
  如果传输文件时出现丢包,Receiver 将不能收到它所期望数量的数据。在上面的示例中,这会导致 Receiver 继续运行,等待剩余的数据。对于这个问题一个可行的解决方案是,receiver 在给定时间跨度之后进行每次传输,调用超时。但为了使此次请求具有目的性,我们要像上面说的那样为包扩展序列号。否则我们无法接收到给定数量的数据,并局限于请求文件的完整传输。
  另一个关于这两个问题的解决方案,在每次正确接收包之后再向 sender 发起接收请求。这个方法消除了丢包的可能性,但却会使传输异常缓慢。
   结语
  上面的实现让文件在主机之间传输变得可行。但如果使用的是 UDP 协议的话,我们就无法保证文件的完整性和接收(顺序)的正确性。我们对解决这些问题进行了大体说明,但具体在实际的文件传输中,对这些问题的最简单的解决方案就是,用 TCP 取代 UDP。
最新内容请见作者的GitHub页:http://qaseven.github.io/

相关文章
|
2月前
|
监控 Java API
Java语言按文件创建日期排序及获取最新文件的技术
这段代码实现了文件创建时间的读取、文件列表的获取与排序以及获取最新文件的需求。它具备良好的效率和可读性,对于绝大多数处理文件属性相关的需求来说足够健壮。在实际应用中,根据具体情况,可能还需要进一步处理如访问权限不足、文件系统不支持某些属性等边界情况。
130 14
|
2月前
|
存储 Java 编译器
深入理解Java虚拟机--类文件结构
本内容介绍了Java虚拟机与Class文件的关系及其内部结构。Class文件是一种与语言无关的二进制格式,包含JVM指令集、符号表等信息。无论使用何种语言,只要能生成符合规范的Class文件,即可在JVM上运行。文章详细解析了Class文件的组成,包括魔数、版本号、常量池、访问标志、类索引、字段表、方法表和属性表等,并说明其在Java编译与运行过程中的作用。
|
2月前
|
存储 人工智能 Java
java之通过Http下载文件
本文介绍了使用Java实现通过文件链接下载文件到本地的方法,主要涉及URL、HttpURLConnection及输入输出流的操作。
110 0
|
3月前
|
存储 Java 数据安全/隐私保护
Java技术栈揭秘:Base64加密和解密文件的实战案例
以上就是我们今天关于Java实现Base64编码和解码的实战案例介绍。希望能对你有所帮助。还有更多知识等待你去探索和学习,让我们一同努力,继续前行!
267 5
|
3月前
|
网络协议 安全 Java
实现Java语言的文件断点续传功能的技术方案。
像这样,我们就完成了一项看似高科技、实则亲民的小工程。这样的技术实现不仅具备实用性,也能在面对网络不稳定的挑战时,稳稳地、不失乐趣地完成工作。
182 0
|
5月前
|
网络协议 Java 开发工具
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
264 1
|
9月前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
1778 65
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
6月前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
7月前
|
存储 算法 Java
解锁“分享文件”高效密码:探秘 Java 二叉搜索树算法
在信息爆炸的时代,文件分享至关重要。二叉搜索树(BST)以其高效的查找性能,为文件分享优化提供了新路径。本文聚焦Java环境下BST的应用,介绍其基础结构、实现示例及进阶优化。BST通过有序节点快速定位文件,结合自平衡树、多线程和权限管理,大幅提升文件分享效率与安全性。代码示例展示了文件插入与查找的基本操作,适用于大规模并发场景,确保分享过程流畅高效。掌握BST算法,助力文件分享创新发展。
|
7月前
|
Java API 数据处理
深潜数据海洋:Java文件读写全面解析与实战指南
通过本文的详细解析与实战示例,您可以系统地掌握Java中各种文件读写操作,从基本的读写到高效的NIO操作,再到文件复制、移动和删除。希望这些内容能够帮助您在实际项目中处理文件数据,提高开发效率和代码质量。
164 4