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/

相关文章
|
28天前
|
Java
有关Java发送邮件信息(支持附件、html文件模板发送)
有关Java发送邮件信息(支持附件、html文件模板发送)
26 1
|
30天前
|
域名解析 网络协议 关系型数据库
tcp和udp的区别是什么
TCP和UDP是互联网协议中的传输层协议。TCP是面向连接的,通过三次握手建立可靠连接,提供数据顺序和可靠性保证,适用于HTTP、FTP等需要保证数据完整性的应用。UDP则是无连接的,数据报独立发送,传输速度快但不保证可靠性,常用于实时通信、流媒体和DNS解析等对速度要求高的场景。根据应用需求选择合适的协议至关重要。
tcp和udp的区别是什么
|
1月前
|
Java
java中替换文件内容
java中替换文件内容
14 1
|
1月前
|
Java API
Java中文件与输入输出
Java中文件与输入输出
|
1月前
|
网络协议 网络性能优化
认识TCP和UDP的区别
重排机制:由于UDP数据包可能因网络原因而发生乱序,因此在应用层需要对接收到的数据包进行排序。
31 4
|
1月前
|
Java
java实现遍历树形菜单方法——映射文件VoteTree.hbm.xml
java实现遍历树形菜单方法——映射文件VoteTree.hbm.xml
9 0
|
1月前
|
Java
java程序导出堆文件
java程序导出堆文件
|
2天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
25 3
|
7天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
30天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
92 3