java实现两台电脑间TCP协议文件传输

  首先明确需求,在同一局域网下的机器人A想给喜欢了很久的机器人B发送情书,但是机器人B事先并不知道小A的心思,那么作为月老(红娘)该如何帮助他们呢?

  然后建立模型并拆分需求。这里两台主机使用网线直连,在物理层上确保建立了连接,接下来便是利用相应的协议将信息从电脑A传给电脑B。在这一步上,可以将此过程抽象为网络+I/O(Input、Output)的过程。如果能在一台电脑上实现文件之间的传输,再加上相互的网络协议,羞涩的A不就可以将情书发送给B了吗?因此要先解决在一台电脑上传输信息的问题。为了在网络上传输,使用必要的协议是必要的,TCP/IP协议簇就是为了解决计算机间通信而生,而这里主要用到UDP和TCP两种协议。当小A可以向小B发送情书后,又出现了众多的追求者,那么小B如何去处理这么多的并发任务呢?这时便要用到多线程的技术。

  因此接下来将分别介绍此过程中所用到了I/O流(最基础)、网络编程(最重要)、多线程知识(较重要)和其中一些小技巧。

一、I/O流

  I/O流用来处理设备之间的数据传输,Java对数据的传输通过流的方式。

  流按操作数据分为两种:字节流与字符流。如果数据是文本类型,那么需要使用字符流;如果是其他类型,那么使用字节流。简单来说,字符流=字节流+编码表。

  流按流向分为:输入流(将硬盘中的数据读入内存),输出流(将内存中的数据写入硬盘)。

  简单来说,想要将某文件传到目的地,需要将此文件关联输入流,然后将输入流中的信息写入到输出流中。将目的关联输出流,就可以将信息传输到目的地了。

  Java提供了大量的流对象可供使用,其中有两大基类,字节流的两个顶层父InputStream与OutputStream;字符流的两个顶层父类Reader与Writer。这些体系的子类都以父类名作为后缀,而子类名的前缀就是该对象的功能。

流对象技巧

  下提供4个明确的要点,只要明确以下几点就能比较清晰的确认使用哪几个流对象。

  1, 明确源和目的(汇)

源     :InputStream       Reader

目的  :OutputStream    Writer

  2, 明确数据是否是纯文本数据

源   :是纯文本  :Reader

           非纯文本  :InputStream

目的:是纯文本  :Writer

           非纯文本  :OutputStream

  到这里就可以明确需求中具体要用哪个体系。

  3, 明确具体的设备。

源设备:

        硬盘:File

        键盘:System.in

        内存:数组

        网络:Socket流

目的设备:

        硬盘:File

        控制台:System.out

        内存:数组

        网络:Socket流

  4,是否需要其他额外功能。

a) 是否需要高效(缓冲区)?

是,就加上buffer。

b) 是否需要转换?

源:InputStreamReader 字节流->字符流

目的:OutputStreamWriter 字符流->字节流

  在这里源为硬盘,目的也为硬盘,数据类型为情书,可能是文字的情书,也可能是小A唱的歌《情书》,因此使用字节流比较好。因此分析下来源是文件File+字节流InputStream->FileInputStream,目的是文件File+字节流OutputStream->FileOutputStream,  接下来便是数据如何从输入流到输出流的问题。

java实现两台电脑间TCP协议文件传输

  两个流之间没有直接关系,需要使用缓冲区来作为中转,为了将读入流与缓冲区关联,首先自定义一个缓冲区数组byte[1024]。为了将读入流与缓冲区关联,使用fis.read(buf);为了将写出流与缓冲区关联,使用fos.write(buf,0,len)。为了将流中的文件写出到输出源中,要使用fos.flush或者fos.close。flush可以多次刷新,而close只能使用一次。

  代码如下,其中读写中会遇到的异常为了程序的清晰阅读,直接抛出,建议实际使用时利用try,catch处理。

1 public class IODemo { 2 /** 3 * 需求:将指定文件从D盘目录d:\1下移动到d:\2下 4 * @param args 5 * @throws IOException 6 */ 7 public static void main(String[] args) throws IOException { 8 //1,明确源和目的,建立输入流和输出流 9 //注意路径需要使用\\,将\转义 10 FileInputStream fis = new FileInputStream("d:\\1\\1.png");//源为d盘1目录下文件1.png 11 FileOutputStream fos = new FileOutputStream("d:\\2\\2.png");//目的为d盘2目录下文件2.png 12 //2,使用自定义缓冲区将输入流和输出流关联起来 13 byte[] buf = new byte[1024];//定义1024byte的缓冲区 14 int len = 0;//输入流读到缓冲区中的长度 15 //3,将数据从输入流读入缓冲区 16 //循环读入,当读到文件最后,会得到值-1 17 while((len=fis.read(buf))!=-1){ 18 fos.write(buf,0,len);//将读到长度部分写入输出流 19 } 20 //4,关流,需要关闭底层资源 21 fis.close(); 22 fos.close(); 23 } 24 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsfzs.html