JAVA 基于TCP协议的一对一,一对多文件传输实现

Posted IT技术指南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 基于TCP协议的一对一,一对多文件传输实现相关的知识,希望对你有一定的参考价值。

最近老师给我们上了多线程和TCP和UDP协议,其中一个要求就是我们用JAVA协议一个基于TCP和UDP这两种协议的一对一文件上传和一对多文件上传。

    然后我就开始分析TCP和UDP这两个协议的特点,发现TCP是流传输,抓住这一点就好实现了。

    现在我们需要解决一下几个问题,

    1.如何确定文件名称

    2.如何完成数据传输,并复原成原来的文件。

    解决方案就是,对象这是个好东西,因为TCP支持流传输的缘故,我们把每个文件对象化,这样我们就很容易实现基于TCP的多文件上传了。

    下面是文件对象代码:

  1. package com.org.gjt.WebSocket.work1.entity;  

  2.   

  3. import java.io.Serializable;  

  4.   

  5. /** 

  6.  * @author gjt 

  7.  * @version 1.0 

  8.  * @Title: 文件实体类 

  9.  * @date 2018/5/24/10:45 

  10.  */  

  11. public class FileSetting implements Serializable{  

  12.     private static final long serialVersionUID = 613659699548582156L;  

  13.     /** 

  14.      * 文件名称 

  15.      */  

  16.     private String fileName;  

  17.     /** 

  18.      * 文件类型 

  19.      */  

  20.     private String fileType;  

  21.     /** 

  22.      * 文件大小 

  23.      */  

  24.     private long size;  

  25.     /** 

  26.      * 文件内容 

  27.      */  

  28.     private String stream;  

  29.     /** 

  30.      */  

  31.     private String originPath;  

  32.   

  33.     public String getOriginPath() {  

  34.         return originPath;  

  35.     }  

  36.   

  37.     public void setOriginPath(String originPath) {  

  38.         this.originPath = originPath;  

  39.     }  

  40.   

  41.     public String getFileName() {  

  42.         return fileName;  

  43.     }  

  44.   

  45.     public void setFileName(String fileName) {  

  46.         this.fileName = fileName;  

  47.     }  

  48.   

  49.     public String getFileType() {  

  50.         return fileType;  

  51.     }  

  52.   

  53.     public void setFileType(String fileType) {  

  54.         this.fileType = fileType;  

  55.     }  

  56.   

  57.     public long getSize() {  

  58.         return size;  

  59.     }  

  60.   

  61.     public void setSize(long size) {  

  62.         this.size = size;  

  63.     }  

  64.   

  65.     public String getStream() {  

  66.         return stream;  

  67.     }  

  68.   

  69.     public void setStream(String stream) {  

  70.         this.stream = stream;  

  71.     }  

  72. }  

其中需要注意的就是,我们需要对文件对象进行序列化。这是一种处理对象流的机制。原理的话网上很多。

下面是TCP的配置实体类 

  1. package com.org.gjt.WebSocket.work1.entity;  

  2.   

  3. /** 

  4.  * @author gjt 

  5.  * @version 1.0 

  6.  * @Title: tcp连接实体 

  7.  * @date 2018/5/24/9:52 

  8.  */  

  9. public class TCPsetting {  

  10.     /** 

  11.      * 设置上传服务器 

  12.      */  

  13.     public final static String conAddr = "127.0.0.1";  

  14.     /** 

  15.      * 设置要上传的端口 

  16.      */  

  17.     public final static int port = 8888;  

  18. }  

 到时候如果要放在服务器上只需要修改conAddr既可。

    下面是TCPSocket端的代码

    单独剥离出来的原因,主要是我希望能尽可能不让开发人员介入底层配置只需要填空即可。后面我还会对这个再一次封装。

  1. package com.org.gjt.WebSocket.work1;  

  2.   

  3. import com.org.gjt.WebSocket.work1.entity.TCPsetting;  

  4.   

  5. import java.io.IOException;  

  6. import java.net.Socket;  

  7.   

  8. /** 

  9.  * @author gjt 

  10.  * @version 1.0 

  11.  * @Title:  tcpSocketClient 

  12.  * @date 2018/5/24/11:10 

  13.  */  

  14. public class TcpSocketClient {  

  15.     /** 

  16.      * 建立socket连接 

  17.      * @return 

  18.      */  

  19.     public  Socket ConnectTcpClient(){  

  20.         Socket clientSocket = null;  

  21.         /** 

  22.          * 建立socket连接 

  23.          */  

  24.         try {  

  25.             clientSocket = new Socket(TCPsetting.conAddr,TCPsetting.port);  

  26.         } catch (Exception e) {  

  27.             e.printStackTrace();  

  28.         }  

  29.         return clientSocket;  

  30.     }  

  31.   

  32.     /** 

  33.      * 关闭连接 

  34.      * @param socket 

  35.      */  

  36.     public  void Close(Socket socket){  

  37.         try {  

  38.             socket.close();  

  39.             System.out.println("关闭成功!");  

  40.         } catch (IOException e) {  

  41.             e.printStackTrace();  

  42.         }  

  43.     }  

  44. }  

下面是TCP协议的Client端

  1. package com.org.gjt.WebSocket.work1;  

  2.   

  3. import com.org.gjt.WebSocket.utils.FileUtils;  

  4. import com.org.gjt.WebSocket.work1.entity.FileSetting;  

  5.   

  6. import java.io.*;  

  7. import java.net.Socket;  

  8. import java.util.Scanner;  

  9.   

  10. /** 

  11.  * @author gjt 

  12.  * @version 1.0 

  13.  * @Title: tcp一对一文件上传:客户端 

  14.  * @date 2018/5/24/9:50 

  15.  */  

  16. public class TCPSingleClient {  

  17.   

  18.     /** 

  19.      * 建立客户端socket连接 

  20.      */  

  21.     private static TcpSocketClient conn  = new TcpSocketClient();  

  22.   

  23.     /** 

  24.      * 设置文件信息 

  25.      */  

  26.     private static FileSetting file = new FileSetting();  

  27.   

  28.     /** 

  29.      * 启动文件工具类 

  30.      */  

  31.     private static FileUtils fileUtils = new FileUtils();  

  32.   

  33.     /** 

  34.      * 发送文件 

  35.      * @param path 

  36.      * @throws Exception 

  37.      */  

  38.     private static void SendFile(String path) throws Exception {  

  39.         Socket connect = conn.ConnectTcpClient();  

  40.         OutputStream os = connect.getOutputStream();  

  41.         ObjectOutputStream oos = new ObjectOutputStream(os);  

  42.         oos.writeObject(file);  

  43.         oos.writeObject(null);  

  44.         oos.flush();  

  45.         connect.shutdownOutput();  

  46.         String infoString=null;  

  47.         InputStream is = connect.getInputStream();  

  48.         BufferedReader br=new BufferedReader(new InputStreamReader(is));  

  49.         String info=null;  

  50.         while((info=br.readLine())!=null){  

  51.             System.out.println("服务器端的信息:" + info);  

  52.         }  

  53.         Scanner sc = new Scanner(System.in);  

  54.         sc.nextInt();  

  55.         connect.shutdownInput();  

  56.         oos.close();  

  57.         os.close();  

  58.         is.close();  

  59.         br.close();  

  60.         conn.Close(connect);  

  61.     }  

  62.   

  63.     /** 

  64.      * 初始化文件并组装 

  65.      * @param path 

  66.      */  

  67.     private static void initFiles(String path) {  

  68.         File selectFile = new File(path);  

  69.         String name = selectFile.getName();  

  70.         String fileOriginPath = selectFile.getPath();  

  71.         String type = name.substring(name.lastIndexOf(".") + 1);  

  72.         String content = fileUtils.encryptToBase64(path);  

  73.         long size = selectFile.length();  

  74.         System.out.println("***************文件基本信息***************");  

  75.         System.out.println("name:"+name);  

  76.         System.out.println("fileOriginPath:"+fileOriginPath);  

  77.         System.out.println("type:"+type);  

  78.         System.out.println("content:"+content);  

  79.         System.out.println("size:"+size);  

  80.         System.out.println("***************文件基本信息***************");  

  81.         file.setFileName(name);  

  82.         file.setSize(size);  

  83.         file.setStream(content);  

  84.         file.setFileType(type);  

  85.         file.setOriginPath(fileOriginPath);  

  86.     }  

  87.     public static void main(String[] args) {  

  88.         String path = "E:\\webstromProject\\eduProject\\classWork\\test.jpg";  

  89.         initFiles(path);  

  90.         try {  

  91.             SendFile(path);  

  92.         } catch (Exception e) {  

  93.             e.printStackTrace();  

  94.         }  

  95.     }  

  96. }  

 TCPserver端  

  1. package com.org.gjt.WebSocket.work1;  

  2.   

  3. import com.org.gjt.WebSocket.utils.FileUtils;  

  4. import com.org.gjt.WebSocket.work1.entity.FileSetting;  

  5. import com.org.gjt.WebSocket.work1.entity.TCPsetting;  

  6.   

  7. import java.io.*;  

  8. import java.net.ServerSocket;  

  9. import java.net.Socket;  

  10.   

  11. /** 

  12.  * @author gjt 

  13.  * @version 1.0 

  14.  * @Title: 一对一上次:服务端 

  15.  * @date 2018/5/24/16:55 

  16.  */  

  17. public class TCPSingleServer {  

  18.   

  19.     /** 

  20.      * 启动文件工具类 

  21.      */  

  22.     private static FileUtils fileUtils = new FileUtils();  

  23.     /** 

  24.      * 接受传输过来的对象 

  25.      */  

  26.     private static FileSetting fileSetting = new FileSetting();  

  27.   

  28.     private static void StartService() throws Exception {  

  29.         Object obj = null;  

  30.         ServerSocket serverSocket = new ServerSocket(TCPsetting.port);  

  31.         System.out.println("服务器启动,等待客户端的连接。。。");  

  32.         Socket socket = serverSocket.accept();  

  33.         OutputStream os = null;  

  34.         PrintWriter pw = null;  

  35.         InputStream is = socket.getInputStream();  

  36.         ObjectInputStream ois=new ObjectInputStream(is);  

  37.         obj = ois.readObject();  

  38.         if (obj != null){  

  39.             System.out.println("接收到来自["+socket.getInetAddress().getHostAddress()+"]的文件");  

  40.             fileSetting = (FileSetting) obj;  

  41.             /** 

  42.              * 开始存储工作 

  43.              */  

  44.             File dir = new File("E:\\"+socket.getInetAddress().getHostAddress());  

  45.             if(!dir.exists()){  

  46.                 dir.mkdir();  

  47.             }  

  48.             File file = new File(dir, socket.getInetAddress().getHostAddress()+fileSetting.getFileName());  

  49.             /** 

  50.              * 获取base64流转为指定文件 

  51.              */  

  52.             String stream = fileSetting.getStream();  

  53.             fileUtils.decryptByBase64(stream,file.getPath());  

  54.             System.out.println("保存成功");  

  55.         }  

  56.         os=socket.getOutputStream();  

  57.         pw=new PrintWriter(os);  

  58.         pw.println("传输完成!");  

  59.         pw.flush();  

  60.         socket.shutdownOutput();  

  61.         if(pw!=null){  

  62.             pw.close();  

  63.         }  

  64.         if(os!=null){  

  65.             os.close();  

  66.         }  

  67.         if(socket!=null){  

  68.             socket.close();  

  69.         }  

  70.     }  

  71.   

  72.     public static void main(String[] args) {  

  73.         try {  

  74.             StartService();  

  75.         } catch (Exception e) {  

  76.             e.printStackTrace();  

  77.         }  

  78.     }  

  79. }  

这是基本代码,实现基于TCP的文件上传。

    修改成一对多也很简单,之后我会把两个版本的代码上传到我的github上去,有想法的大佬可以下载下来试试。

    关于修改成多文件上传,只需要在原来传输对象基础上修改成对象列表即可。

代码链接:https://github.com/1163236754/JAVA-Code/tree/master/WebSocket/work1

以上是关于JAVA 基于TCP协议的一对一,一对多文件传输实现的主要内容,如果未能解决你的问题,请参考以下文章

TCP协议和UDP协议区别

TCP和UDP的区别

java面试题-tcp和udp

网络编程

tcp和udp有啥区别

网络七层协议