网络编程_多线程的文件上传小示例

http://blog.csdn.net/zsw101259/article/details/7768908

1、多线程文件的上传,数据流向 

1)、客户端Socket:

      ①out File对象 

       ②out 文件内容

        ③in 服务端反馈信息 


2)、服务端的处理 

       ①每接收一个Socket,创建一个线程去处理这个Socket 

        ②in File对象:判断文件的类型、选择不同的传输方式、创建File对象关联文件

        ③in 文件内容:填充File对象关联文件内容 

       ④填充完File文件,给客户端反馈

  

   2、代码:                 

  1)客户端:字符流       

 

[java] view plaincopy
  1. import java.net.*;  
  2. import java.io.*;  
  3. /** 
  4.  * @author Administrator @zsw 2012-7-18 上午09:21:04 
  5.  *  
  6.  * 需求:从客户端上传文本文件到服务端 
  7.  *  
  8.  * 客户端上传: 
  9.  * ①定义Socket、文件输入流、Socket输出流、Socket输入流 
  10.  * ②从文件输入读取文件, 
  11.  * 添加:首先上传文件File对象和文件类型int filetype 
  12.  * ③将读到的数据写入Socket输出流中 
  13.  * ④关闭资源 
  14.  */  
  15. public class TextUploadClient2 {  
  16.   
  17.       
  18.     public static void main(String[] args) throws Exception{  
  19.         File file=new File("D:\\1.txt");  
  20.           
  21.           
  22.         //①:定义资源  
  23.         Socket s=new Socket("127.0.0.1",10007);  
  24.         BufferedReader bufr=new BufferedReader(new FileReader(file));  
  25.         //字符流转换成字节流  
  26.         BufferedWriter bufout=new BufferedWriter(  
  27.                 new OutputStreamWriter(s.getOutputStream()));  
  28. //      PrintWriter out=new PrintWriter(s.getOutputStream(),true);  
  29.         BufferedReader bufin=new BufferedReader(  
  30.                 new InputStreamReader(s.getInputStream()));  
  31.           
  32.         //将文件对象传到服务器  
  33.         ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());  
  34.         oos.writeObject(file);  
  35.           
  36.       
  37.         //②上传数据  
  38.         String line=null;  
  39.         while((line=bufr.readLine())!=null){  
  40.                
  41. //          System.out.println(line);  
  42.             bufout.write(line);  
  43.             bufout.newLine();  
  44.             bufout.flush();  
  45.         }  
  46.           
  47.         //③告诉服务器,客户端已经传完了。并接收服务端的反馈信息  
  48.          s.shutdownOutput();//关闭客户端的输出流,相当于在流中写-1  
  49.            
  50.          String line2=null;  
  51.          while((line2=bufin.readLine())!=null){  
  52.              if("success".equals(line2)){     
  53.                  System.out.println("上传文件成功!");  
  54.                  break;  
  55.              }  
  56.          }  
  57.           
  58.         //④关闭资源  
  59.          bufr.close();  
  60.          s.close();  
  61.   
  62.   
  63.     }  
  64.   
  65. }  

                                     

2)客户端:字符流


[java] view plaincopy
  1. import java.io.*;  
  2. import java.net.*;   
  3. /** 
  4.  * @author Administrator @zsw 2012-7-18 下午06:45:41 
  5.  *客户端: 
  6.  *①服务端点:Socket、流 
  7.  *②读取客户端的图片数据 
  8.  *③通过Socket输出流将数据发给服务端 
  9.  *④读取服务端反馈信息 
  10.  *⑤关闭资源 
  11.  */  
  12. public class UploadPicClient2 {  
  13.     public static void main(String[] args) throws Exception{  
  14.         File file=new File("D:\\1.mp3");  
  15.         //①服务端点:  
  16.         Socket s=new Socket("127.0.0.1",10007);  
  17.         FileInputStream fis=new FileInputStream(file);  
  18.         OutputStream out=s.getOutputStream();  
  19.         InputStream in=s.getInputStream();  
  20.           
  21.         //将文件对象传到服务器  
  22.         ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());  
  23.         oos.writeObject(file);  
  24.           
  25.         //②读取图片  
  26.         byte[]buf=new byte[1024*2];  
  27.         int len=0;  
  28.         while((len=fis.read(buf))!=-1){  
  29.             //③发送数据到服务端  
  30.             out.write(buf, 0, len);   
  31.         }  
  32.         //给服务端发送结束标记  
  33.         s.shutdownOutput();  
  34.           
  35.         //④读取服务端反馈信息  
  36.         len=0;  
  37.         while((len=in.read(buf))!=-1){  
  38.             String str=new String(buf,0,len);  
  39.             System.out.println("服务端反馈:"+str);  
  40.         }  
  41.           
  42.         //⑤关闭资源  
  43.         fis.close();  
  44.         s.close();  
  45.     }  
  46.   
  47. }  

3)服务端:使用多线程

[java] view plaincopy
  1. import java.io.*;  
  2. import java.net.*;  
  3.   
  4. /** 
  5.  * 总结:多线程文件的上传,数据流向 
  6.  * 1、客户端Socket:①out File对象 ②out 文件内容 ③in 服务端反馈信息 
  7.  *            
  8.  * 3、服务端的处理 
  9.  *  ①每接收一个Socket,创建一个线程去处理这个Socket 
  10.  *  ②in File对象:判断文件的类型、选择不同的传输方式、创建File对象关联文件 
  11.  *  ③in 文件内容:填充File对象关联文件内容 
  12.  *  ④填充完File文件,给客户端反馈 
  13.  *   
  14.  *   
  15.  * @author Administrator @zsw 2012-7-18 下午07:03:47 
  16.  * 此类在UploadPicServer.java上面做改进,使用了多线程. 
  17.  *  
  18.  *1单线程服务端:有局限,当A客户连接上来后,<br> 
  19.  *被服务器接收后, 服务端执行具体流程中,这时,B客户端连接,只有等待。 
  20.  *因为服务端还没有处理完A客户端的请求, 
  21.  *还没有循环回来执行下次 accept方法,所以暂时获取不到B客户端对象 
  22.  *  
  23.  *2解决思路:那么为了可以让多个客户端同时并发的访问服务器,  
  24.  *服务端最好就是将每一个客户端封装到一个单独的线程中。 
  25.  *  
  26.  *  
  27.  *  
  28.  */  
  29. /* 
  30.  * 如何定义线程呢: 明确每一个客户端要在服务端执行的代码,将该代码放入run方法中 
  31.  */  
  32. //3、线程类  
  33. class UploadThread implements Runnable {  
  34.     // 客户端、文件、文件类型(简单点0表示文本、1表示字节流)  
  35.     private Socket s;  
  36.     UploadThread(Socket s) {  
  37.         this.s = s;   
  38.     }  
  39.     public void run() {  
  40.         try {  
  41.             Thread.sleep(5000);  
  42.             new FileUpload().upload(s);  
  43.               
  44.         } catch (InterruptedException e) {  
  45.             // TODO Auto-generated catch block  
  46.             e.printStackTrace();  
  47.         }  
  48.           
  49.   
  50.     }  
  51.   
  52. }  
  53.   
  54. // 1、主程序  
  55. public class UploadPicByThread {  
  56.     public static void main(String[] args) throws Exception {  
  57.         // ①定义服务端点:  
  58.         ServerSocket ss = new ServerSocket(10007);  
  59.         //②为每一个客户端开启一个  
  60.         int cNum=0;  
  61.         while (true) {  
  62.             Socket s = ss.accept();  
  63.             cNum++;  
  64.             new Thread(new UploadThread(s)).start();  
  65.             System.out.println("上传成功文件数:"+cNum);  
  66.         }  
  67.   
  68.     }  
  69. }  


4、服务端:业务类,根据不同的上传,选择不同的方式

 

[java] view plaincopy
  1. import java.io.*;  
  2. import java.net.*;  
  3.   
  4. // 2、业务类  
  5. public class FileUpload {  
  6.   
  7.     public void upload(Socket s) {  
  8.         try {  
  9.             ObjectInputStream ois=new ObjectInputStream(s.getInputStream());  
  10.             File file=(File)ois.readObject();  
  11.             //当发现文件存在时,修改文件名:如 1.mp3->(count++)1.mp3  
  12.             String name=file.getName();//原始文件名  
  13.             File dir=new File("D:\\tx\\");  
  14.             file=new File(dir,name);  
  15.             int count=0;  
  16.             while(file.exists()){  
  17.                 count++;  
  18.                 file=new File(dir,"("+count+")"+name);  
  19.             }  
  20.             /*当时文本文件时,调用文本上传方法 
  21.              * 否则调用字符流上传方法 
  22.              */  
  23.               
  24.             if(name.endsWith(".txt")){  
  25.                 textUpload(s,file);  
  26.             }else{  
  27.                 picUpload(s,file);  
  28.             }  
  29.               
  30.         }  catch (Exception e) {  
  31.             System.out.println(e);  
  32.             System.out.println("上传失败");  
  33.         }  
  34.           
  35.     }  
  36.   
  37.     // ①图片等多媒体文件上传(字节流)  
  38.     public void picUpload(Socket s, File file)  throws Exception{  
  39.   
  40.             //打印客户端  
  41.             String ip=s.getInetAddress().getHostAddress();  
  42.             System.out.println(ip+"....connect 准备上传"+file.getName());  
  43.               
  44.             FileOutputStream fos = new FileOutputStream(file);  
  45.             InputStream in = s.getInputStream();  
  46.             OutputStream out = s.getOutputStream();  
  47.   
  48.   
  49.             // ②读取数据  
  50.             int len = 0;  
  51.             byte[] buf = new byte[1024 * 2];  
  52.             while ((len = in.read(buf)) != -1) {  
  53.                 fos.write(buf, 0, len);  
  54.             }  
  55.             // ③给客户端反馈  
  56.             System.out.println(file.getName()+"服务端接收完成");  
  57.             out.write("success".getBytes());  
  58.             // 给客户端发送结束标记  
  59.             s.shutdownOutput();  
  60.   
  61.             // ④关闭资源  
  62.             fos.close();  
  63.             s.close();  
  64.           
  65.   
  66.     }  
  67.   
  68.     // ②文本上传(字符流)  
  69.     public void textUpload(Socket s, File file) throws Exception {  
  70.           
  71.             //打印客户端连接的  
  72.             String ip=s.getInetAddress().getHostAddress();  
  73.             System.out.println(ip+"....connect 准备上传"+file.getName());  
  74.               
  75.             BufferedWriter bufw = new BufferedWriter(new FileWriter(file));  
  76.             // Socket 输出输入  
  77.             BufferedReader bufin = new BufferedReader(new InputStreamReader(  
  78.                     s.getInputStream()));  
  79.             BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(  
  80.                     s.getOutputStream()));  
  81.   
  82.             // ②:读数据、写到文件、判断结束、反馈成功  
  83.             String line = null;  
  84.             /* 
  85.              * 服务端收不到line=null的情况,必须在流中添加结束标记 s.shutdownOutput(); 
  86.              * 关闭客户端的输出流,相当于在流中写-1,line就可以=null 
  87.              */  
  88.             // 获取标记符(即时间值)  
  89.             while ((line = bufin.readLine()) != null) {  
  90.                 bufw.write(line);  
  91.                 bufw.newLine();  
  92.                 bufw.flush();  
  93.   
  94.             }  
  95.             System.out.println(file.getName()+"数据接收成功!");  
  96.             bufout.write("success");  
  97.             bufout.newLine();  
  98.             bufout.flush();  
  99.             s.shutdownOutput();  
  100.   
  101.             // 关闭资源  
  102.             bufw.close();  
  103.             s.close();  
  104.           
  105.     }  
  106. }  


上一篇:Java多线程


下一篇:Android开发 CardView卡片View的详解