• 郑州北大青鸟首页
  • 网站导航
  • 河南软件与网络工程师培养基地 河南拥有IT体验馆课程专业全、规模大校区河南多年连获全国教学质量奖2011-2019年获北大青鸟总部荣誉奖
首页 中心介绍 新闻动态 课程详解 师资力量 专家讲座 招生问答 学员活动 精彩专题 报名
当前位置: > 专家讲座 > 免费技术讲座 >

java文件的Socket传输是怎么传输呢?

2015-11-16 15:07 来源:郑州北大青鸟
java文件的Socket传输是怎么传输呢?前段时间的项目中需要实现网络硬盘的功能, 所以整理了Java的Socket文件传输, 方便以后重用! 
 
大家都知道Java语言功能强大, 对网络传输的支持更强, Socket和多线程是程序员必备知识. 
 
为了方便项目布署, 服务器没有使用FTP服务器, 全是由纯Java所写. 
 
除了文件传输外, 自定义了传输协议, 即在同一个流中, 增加了文件的一些属性. 
 
 
服务器端核心代码: 
 
Java代码  
Thread fileThread = new Thread(){   
   public void run(){   
    try {   
     ServerSocket ss = new ServerSocket(port, maxConnected);   
     System.out.println("文件传输服务启动成功!");   
     while(true){   
      Socket socket = ss.accept();   
      Thread trFile = new TrFile(socket);   
      //trFile.setDaemon(true);   
      trFile.start();   
     }   
    } catch (Exception e1) {   
     e1.printStackTrace();   
    }   
   }   
   class TrFile extends Thread{   
    private Socket socket;   
    private String UPLOAD_TYPE = "/example";        // value = /gamesave or /webdisk   
    private String USER_DIR = "/example";         // value = /username   
  
  
    private String childFilename = null;   
    private String childFileaddr = null;   
    private String childGame = null;   
    private String childFiletype = null;   
    private String childUserid = null;   
    private String childFilesize = null;   
    public TrFile(Socket socket){   
     this.socket = socket;   
    }   
    public void run(){   
     try{   
               InputStream in =   
                         socket.getInputStream();   
               PrintWriter out =   
                     new PrintWriter(   
                       new BufferedWriter(   
                         new OutputStreamWriter(   
                           socket.getOutputStream())),true);   
  
               while(true)   
               {   
                   //第一个参数为命令   
  
                   String cmds = getFileInfo(in, 128);   
                   /*  
                   if("exit".equals(cmds)){  
                       System.exit(0);  
                   } else */   
                   if("cp".equals(cmds)){   
  
                    //获得用户名   
                    childUserid = getFileInfo(in, 30);   
  
                    //获得网吧硬盘目录   
                    childFiletype = getFileInfo(in, 128);   
  
                    //获得游戏   
                    childGame = getFileInfo(in, 128);   
  
                    //获得文件名   
                    childFilename = getFileInfo(in, 256);   
  
                       //获得文件大小   
                    childFilesize = getFileInfo(in, 128);   
                       //获得其它属性...   
  
                    //做一些目录的处理   
                    USER_DIR = "/" + childUserid;   
        if (childGame.equals("")){   
         //网络硬盘   
         USER_DIR += "/"+childFiletype;   
         UPLOAD_TYPE = "/webdisk";   
        }else{   
         //游戏存档   
  
         USER_DIR = USER_DIR + "/" + childGame;   
         UPLOAD_TYPE = "/gamesave";   
        }   
  
        //在服务器创建目录   
        File folder = new File(APP_CONTEXT+UPLOAD_ROOT+UPLOAD_TYPE+USER_DIR);   
        if (!folder.exists()){   
         folder.mkdirs();   
        }   
        File fileout = new File(folder, childFilename);   
  
                       //如果文件已存在, 则在文件名尾追加(i)命名.   
                       int fileEndIndex = 0;   
                       while(fileout.exists()){   
                        String[] newFileNames = FileUtil.splitFileNameHasDot(childFilename);   
                        String newFileName = newFileNames[0] + "(" + (++fileEndIndex) + ")" + newFileNames[1];   
                        fileout = new File(folder,newFileName);   
                       }   
                       if (fileEndIndex!=0){   
                        String[] newFileNames = FileUtil.splitFileNameHasDot(childFilename);   
                        childFilename = newFileNames[0] + "(" + fileEndIndex + ")" + newFileNames[1];   
                       }   
        //创建新文件   
                       fileout.createNewFile();   
                       FileOutputStream fos = new FileOutputStream(fileout);   
  
                       int ta = Integer.parseInt(childFilesize);   
                       byte[] buf = new byte[1024*10];   
                       //InputStream ins = socket.getInputStream();   
                       while(true){   
                           if(ta==0){   
                               break;   
                           }   
                           int len = ta;   
                           if(len>buf.length){   
                               len = buf.length;   
                           }   
                           int rlen = in.read(buf, 0, len);   
  
                           //int rlen = ins.read(buf, 0, len);   
                           ta -= rlen;   
                           if(rlen>0){   
                               fos.write(buf,0,rlen);   
                               fos.flush();   
                           }   
                           else{   
                               break;   
                           }   
                       }   
                       out.println("cp finish!");   
                       fos.close();   
  
                       System.out.println("服务器端已存储文件: " + fileout.getPath());   
                       childFileaddr = "/"+UPLOAD_ROOT+UPLOAD_TYPE+USER_DIR+"/"+childFilename;   
  
        if (childGame.equals("")){   
         WebdiskLog wl = new WebdiskLog();   
         wl.setUsername(childUserid);   
         wl.setFilename(childFileaddr);   
         wl.setFilesize(childFilesize);   
         wl.setUploadtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new GregorianCalendar().getTime()));   
         new WebdiskLogDAO().add(wl, null);   
         System.out.println("服务器端已写入webdisk上传日志数据库: " + childFileaddr);   
        }else{   
  
        }   
  
                       break;   
                   }   
                   else{   
                       System.out.println("err command!");   
                       out.println("err command!");   
                       break;   
                   }   
               }   
               socket.close();   
           }catch(Exception e){   
               e.printStackTrace();   
  
           }   
    }   
  
    String getFileInfo(InputStream in, int len){   
     String result = null;   
     try{   
      byte cmd[] = new byte[len];   
                  int b = 0;   
                  while(b<cmd.length){   
                      b += in.read(cmd, b, cmd.length-b);   
                  }   
                  int ends = 0;   
                  for(int i=0;i<cmd.length;i++){   
                      if(cmd==0x00000000){   
                          ends = i;   
                          break;   
                      }   
                  }   
                  result = new String(cmd,0,ends);   
     }catch(Exception ex){   
      ex.printStackTrace();   
     }   
                 return result;   
    }   
   }   
  };   
  fileThread.setDaemon(true);   
  fileThread.start();   
 
 
 
客户端核心代码: 
 
Java代码  
Thread uploadThread = new Thread(){   
    final String localPath = newItemTableItem.getText(0);   
    final String realFilename = newItemTableItem.getText(3);   
    final String uploadFolder = newItemTableItem.getText(2);   
    final TableItem childTi = newItemTableItem;   
    final TableEditor te = (TableEditor)childTi.getData();   
    final ProgressBar pb = (ProgressBar)te.getEditor();   
    public void run(){   
     try {   
  
      InetAddress addr = InetAddress.getByName(Config.getInstance().getProperty("inner_web_ip"));   
            Socket socket =   
                  new Socket(addr, Integer.valueOf(Config.getInstance().getProperty("webdisk_savegame_port")).intValue());   
            OutputStream out = socket.getOutputStream();   
  
            File filein = new File(localPath);   
  
            //发送命令   
            sendFileInfo(out, 128, "cp");   
  
            //发送用户名   
            sendFileInfo(out, 30, AppManager.user.getUsername());   
  
            //发送网吧硬盘目录   
            sendFileInfo(out, 128, uploadFolder);   
  
            //发送游戏   
            sendFileInfo(out, 128, "");   
  
            //发送文件名   
            sendFileInfo(out, 256, realFilename);   
  
            //发送文件大小   
            sendFileInfo(out, 128, ""+filein.length());   
  
            //发送其它信息...   
  
            FileInputStream fis = null;   
            byte[] buf = new byte[1024*10];   
            //char[] bufC = new char[1024*10];   
            fis = new FileInputStream(filein);   
            int readsize = 0;   
            int countNum = 0;   
            //OutputStream ops = socket.getOutputStream();   
            while((readsize = fis.read(buf, 0, buf.length))>0){   
                out.write(buf,0,readsize);   
                out.flush();   
                countNum+=readsize;   
       final int progress = countNum;   
       Display.getDefault().asyncExec(new Runnable(){   
        public void run(){   
         //更新进度   
         pb.setSelection(progress);   
         //pb.redraw();   
        }   
       });   
            }   
            out.close();   
            socket.close();   
            fis.close();   
  
      Display.getDefault().asyncExec(new Runnable(){   
       public void run(){   
        pb.setSelection(pb.getMaximum());   
        childTi.setImage(0, ImageManager.getInstance().getInterfaceImage(display, "udload_susseful.gif"));   
        getFileList(null, null, null, null, null);   
       }   
      });   
     } catch (Exception ex) {   
      ex.printStackTrace();   
  
      if (pb.getSelection()==pb.getMaximum()){   
       childTi.setImage(0, ImageManager.getInstance().getInterfaceImage(display, "udload_susseful.gif"));   
      }else{   
       childTi.setImage(0, ImageManager.getInstance().getInterfaceImage(display, "udload_failed.gif"));   
      }   
     }   
    }   
  
    void sendFileInfo(OutputStream out, int len, String content){   
     try{   
      byte[] cmd = new byte[len];   
            byte[] tcmd = content.getBytes();   
            for(int i=0;i<tcmd.length;i++){   
                cmd = tcmd;   
            }   
            cmd[tcmd.length] = 0x00000000;   
            out.write(cmd,0,cmd.length);   
     }catch(Exception ex){   
      ex.printStackTrace();   
     }   
    }   
   };   
   //uploadThread.setDaemon(true);   
   uploadThread.start();   
 
 
这里要注意的是, 既然是自定义的传输协议, 在文件流之前传输的字节必须是事先定义好的, 例如: 客户端向服务器发送了5个文件额外属性, 标识此文件信息, 则服务器读取时要先将这5个属性读出来, 而且客户端写入时每个属性的字节长度必须和服务器读取时使用的字节长度相同, 否则便失败了! 另外, 每个属性之间的字节间隔我使用了16进制的 0x00000000 来标识, 以便服务器端读取时分隔.
 
 
 
 
 
 
------分隔线----------------------------
栏目列表
联系郑州北大青鸟
  • 学校地址:郑州市金水区文化路90号河南财经政法大
  • 学文南校区1号楼(文化路与俭学街路交叉口文化路
  • 向北300米)
  • 咨询热线:0371-63383521 63383522
  • 6路,28路,966路到文化路与俭学街站下车
企业预订人才热线:0371-63383521
就业服电话:0371-55902629
教学监督:0371-55690491
郑州北大青鸟软件学院地址:郑州市文化路90号河南财经政法
大学文南校区1号楼
传真:0371-63383562 邮政编码:450000
备案号:豫ICP备10022989号-2
版权归 郑州北大青鸟翔天信鸽IT学校
咨询电话:0371-63383521 15225191462
北大青鸟郑州翔天信鸽授权IT软件学院
教育改变生活