Java网络编程多线程改进上传文件
服务器的代码用线程进行封装(多线程),这样可以模拟一个同时接收多人上传文件的服务器。
(用循环也可以但是效率低,是单线程的程序)
/*
* 通过while循环可以改进一个服务器接收多个客户端。
* 但是这个是有问题的。
*
* 如果是以下这种情况:假设我还有张三,李四,王五这三个人分别执行客户端
* 文件大小 网速
* 张三:好好学习.avi(100M) 256k
* 李四:天天向上.mp3(3M) 1M
* 王五:ILoveJava.txt(1k) 100M
*
* 因为服务器端是阻塞式接收的。只有等某一个人上传文件完后才继续执行程序。效率低。
*
* 如何解决呢?
* 给每一个用户分别开启一个线程。
*
*/
示例代码如下:
1 package cn.itcast_15; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileReader; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.io.OutputStreamWriter; 9 import java.net.Socket; 10 11 public class UploadClient { 12 public static void main(String[] args) throws IOException { 13 // 创建客户端Socket对象 14 Socket s = new Socket("192.168.40.9", 11111); 15 16 // 封装文本文件 17 BufferedReader br = new BufferedReader(new FileReader("src//cn//itcast_15//a.txt")); 18 19 // 封装通道内的流对象 20 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 21 22 String line = null; 23 while ((line = br.readLine()) != null) { // 阻塞 24 bw.write(line); 25 bw.newLine(); 26 bw.flush(); 27 } 28 29 // Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了 30 s.shutdownOutput(); 31 32 // 接收反馈 33 BufferedReader brClient = new BufferedReader(new InputStreamReader( 34 s.getInputStream())); 35 String client = brClient.readLine(); // 阻塞 36 System.out.println(client); 37 38 // 释放资源 39 br.close(); 40 s.close(); 41 } 42 }
1 package cn.itcast_15; 2 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 7 public class UploadServer { 8 public static void main(String[] args) throws IOException { 9 // 创建服务器Socket对象 10 ServerSocket ss = new ServerSocket(11111); 11 12 while (true) { 13 Socket s = ss.accept(); // 监听客户端连接 14 new Thread(new UserThread(s)).start(); 15 } 16 } 17 18 }
1 package cn.itcast_15; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileWriter; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.io.OutputStreamWriter; 9 import java.net.Socket; 10 11 public class UserThread implements Runnable { 12 13 private Socket s; 14 15 public UserThread(Socket s) { 16 this.s = s; 17 } 18 19 @Override 20 public void run() { 21 try { 22 // 封装通道内的流对象 23 BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 24 25 // 封装文本文件对象 26 // BufferedWriter bw = new BufferedWriter(new FileWriter("src//cn//itcast_15//Copy.java")); 27 28 // 为了防止名称冲突(即为了防止所有文件的名字都一样) 29 String newName = System.currentTimeMillis() + ".txt"; 30 BufferedWriter bw = new BufferedWriter(new FileWriter("src//cn//itcast_15//" + newName)); 31 // 如果在某一时间点,同时有很多人访问服务器,相同名字的文件也会出现很多,肿么办? 答:再加循环判断,一旦某个名字存在,就重新赋值另一名字即可。 32 33 String line = null; 34 while ((line = br.readLine()) != null) { // 阻塞 35 bw.write(line); 36 bw.newLine(); 37 bw.flush(); 38 } 39 40 // 给出反馈 41 BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 42 bwServer.write("文件上传成功"); 43 bwServer.newLine(); 44 bwServer.flush(); 45 46 // 释放资源 47 bw.close(); 48 s.close(); 49 } catch (IOException e) { 50 e.printStackTrace(); 51 } 52 } 53 54 }
我的GitHub地址: https://github.com/heizemingjun
我的博客园地址: http://www.cnblogs.com/chenmingjun
我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun
Copyright ©2018 黑泽明军
【转载文章务必保留出处和署名,谢谢!】