RSA加密Socket传输文件、签名(二)

服务器端采用多线程方式并行处理传输请求以提高效率。

因为我想用JavaServiceWrapper将 程序作为windows服务运行,所以main方法中需接收一些参数,比如端口、密钥文件位置、文件存放路径等。

1.从main方法接受配置参数

 

  1. for(String arg : args){  
  2.             String argName = arg.substring(0,arg.indexOf(":")).trim();  
  3.             String argValue = arg.substring(arg.indexOf(":")+1).trim();  
  4.             if(argName.equals("rsa_private")){  
  5.                 privateKey = argValue;  
  6.             }else if(argName.equals("rsa_public")){  
  7.                 publicKey = argValue;  
  8.             }else if(argName.equals("port")){  
  9.                 port = Integer.parseInt(argValue);  
  10.             }else if(argName.equals("file_dir")){  
  11.                 file_dir = argValue;  
  12.             }  
  13.         }  

 

 

 

2.初始化解密、签名类实例

 

  1. RSASecurityCoder coder = new RSASecurityCoder(privateKey);  
  2. RSASecuritySignature sign = new RSASecuritySignature(publicKey);  

 

 

 

3.建立服务器

 

  1. private static void runServer(String[] args){  
  2.         long start = System.currentTimeMillis();  
  3.         //获取配置参数   
  4.         for(String arg : args){  
  5.             String argName = arg.substring(0,arg.indexOf(":")).trim();  
  6.             String argValue = arg.substring(arg.indexOf(":")+1).trim();  
  7.             if(argName.equals("rsa_private")){  
  8.                 privateKey = argValue;  
  9.             }else if(argName.equals("rsa_public")){  
  10.                 publicKey = argValue;  
  11.             }else if(argName.equals("port")){  
  12.                 port = Integer.parseInt(argValue);  
  13.             }else if(argName.equals("file_dir")){  
  14.                 file_dir = argValue;  
  15.             }  
  16.         }  
  17.           
  18.         //配置    
  19.         coder = new RSASecurityCoder(privateKey);  
  20.         sign = new RSASecuritySignature(publicKey);  
  21.         //启动服务器   
  22.         System.out.println("服务器启动中...");  
  23.         try {  
  24.             ss = new ServerSocket(port);  
  25.             clientCount = 0;  
  26.         } catch (NumberFormatException e) {  
  27.             System.err.println("端口配置错误");  
  28.         } catch (IOException e) {  
  29.             System.err.println("服务器在端口"+port+"启动失败");  
  30.         }  
  31.           
  32.         //文件存放目录   
  33.         dir = new File(file_dir);  
  34.         if(!dir.exists()){  
  35.             dir.mkdir();  
  36.         }  
  37.         System.out.println("服务器已启动,端口: "+port);  
  38.         //计算启动时间   
  39.         long end = System.currentTimeMillis();  
  40.         System.out.println("共消耗 "+(end-start)+" ms.");  
  41.           
  42.         //接收数据   
  43.         while(true){  
  44.             try {  
  45.                 if(ss == null){  
  46.                     ss = new ServerSocket(port);   
  47.                     clientCount = 0;  
  48.                 }  
  49.                 Socket socket = ss.accept();  
  50.                 clientCount += 1;  
  51.                 System.out.println("有新的连接,当前总连接数:"+clientCount);  
  52.                 Thread th = new Thread(new ServerProcessor(socket));  
  53.                 th.start();  
  54.             } catch (IOException e) {  
  55.                 e.printStackTrace();  
  56.             }  
  57.         }  
  58.           
  59.     }  

 

 

 

 

3.建立线程类ServerProcessor处理每个文件

 

  1. static class ServerProcessor extends Thread{  
  2.         private Socket socket;  
  3.         private InputStream in;  
  4.         private String filename;  
  5.         private long totalBytes;  
  6.         private File file;  
  7.         private FileOutputStream fos;  
  8.         public ServerProcessor(Socket socket){  
  9.             this.socket = socket;  
  10.         }  
  11.         @Override  
  12.         public void run(){  
  13.             try {  
  14.                 in = socket.getInputStream();  
  15.                 DataInputStream dis = new DataInputStream(in);  
  16.                 filename = dis.readUTF();         //读取文件名   
  17.                 totalBytes = dis.readLong();      //读取文件大小    
  18.                 file = new File(dir,filename);  
  19.                 fos = new FileOutputStream(file);  
  20.                 //FileOutputStream fos = new FileOutputStream(File.createTempFile(filename, null, dir));   
  21.                 //输出日志   
  22.                   
  23.                 //RSA加密以128 bytes位单位,一次最多加密117bytes.   
  24.                 byte[] buf = new byte[128];  
  25.                 int available;  
  26.                 while((available = in.read(buf)) != -1){  
  27.                     //读取签名   
  28.                     byte[] signature = buf;  
  29.                     //读取数据   
  30.                     buf = new byte[128];  
  31.                     available = in.read(buf);  
  32.                     byte[] availableBytes = null;  
  33.                     if(available == buf.length){  
  34.                         availableBytes = buf;  
  35.                     }else{  
  36.                         availableBytes = new byte[available];  
  37.                         for (int i = 0; i < available; i++) {  
  38.                             availableBytes[i] = (Byte) buf[i];  
  39.                         }  
  40.                     }  
  41.                       
  42.                     //验证数据签名   
  43.                     boolean flag = sign.verifySignature(availableBytes, signature);  
  44.                     //写入数据   
  45.                     if(flag){  
  46.                         //count += availableBytes.length;   
  47.                         fos.write(coder.decrypt(availableBytes));  
  48.                         //System.out.println(""+count+" bytes received");   
  49.                     }  
  50.                 }  
  51.                 fos.close();  
  52.                 socket.shutdownInput();  
  53.                 clientCount -= 1;  
  54.                 System.out.println("有连接断开,当前总连接数:"+clientCount);  
  55.                 System.out.println(new SimpleDateFormat("[yyyy-MM-DD HH:mm:ss ]").format(new Date())  
  56.                     +filename+" 接收完毕. 大小 "+(totalBytes/1024)+" kb,保存路径:"+dir.getAbsolutePath());  
  57.             } catch (NumberFormatException e) {  
  58.                 System.err.println("端口配置错误");  
  59.                 e.printStackTrace();  
  60.             } catch (FileNotFoundException e) {  
  61.                 System.err.println("文件没找到,文件名:"+filename+",可能是因为读取socket数据失败");  
  62.                 e.printStackTrace();  
  63.             } catch (IOException e) {  
  64.                 System.err.println("文件读/写错误");  
  65.                 try {  
  66.                     fos.close();  
  67.                 } catch (IOException e1) {  
  68.                     e1.printStackTrace();  
  69.                 }  
  70.                 file.delete();  
  71.                 e.printStackTrace();  
  72.             }  
  73.         }  
  74.     }  

 

 

 

main方法

 

  1. public static void main(String[] args) {  
  2.           
  3.         runServer(args);  
  4.           
  5.     } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值