Java 网络编程案例三:多个客户端上传文件

  需求:每一个客户端启动后都可以给服务器上传一个文件,服务器接收到文件后保存到一个upload目录中。可以同时接收多个客户端的文件上传。

  分析:

  (1)服务器端要“同时”处理多个客户端的请求,那么必须使用多线程,每一个客户端的通信需要单独的线程来处理。

  (2)服务器保存上传文件的目录只有一个upload,而每个客户端给服务器发送的文件可能重名,所以需要保证文件名的唯一。我们可以使用“时间戳”作为文件名,而后缀名不变

  (3)客户端需要给服务器上传文件名(含后缀名)以及文件内容。而文件名是字符串,文件内容不一定是纯文本的,因此选择DataOutputStream和DataInputStream。

  客户端的实例代码:

 1 import java.io.BufferedReader;
 2 import java.io.DataOutputStream;
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.InputStream;
 6 import java.io.InputStreamReader;
 7 import java.io.OutputStream;
 8 import java.net.Socket;
 9 import java.util.Scanner;
10
11 public class Client {
12     public static void main(String[] args) throws Exception {
13         // (1)连接服务器
14         Socket socket = new Socket("192.168.54.68", 8888);
15
16         Scanner input = new Scanner(System.in);
17
18         //(2)从键盘输入文件的路径和名称
19         System.out.print("请选择要上传的文件:");
20         String path = input.nextLine();
21         File file = new File(path);
22
23         OutputStream out = socket.getOutputStream();
24         DataOutputStream dos = new DataOutputStream(out);//用它的目的是为了既可以单独传一个字符串,又可以写字节内容
25
26         //先发送文件名(含后缀名)
27         dos.writeUTF(file.getName());//单独发一个字符串
28
29         //还需要一个IO流,从文件读取内容,给服务器发过去
30         FileInputStream fis = new FileInputStream(file);
31
32         //(3)把文件内容给服务器传过去,类似与复制文件
33         byte[] data = new byte[1024];
34         while(true){
35             int len = fis.read(data);
36             if(len==-1){
37                 break;
38             }
39             dos.write(data, 0, len);
40         }
41         socket.shutdownOutput();
42
43         //(4)接收服务器返回的结果
44         InputStream is = socket.getInputStream();
45         InputStreamReader isr = new InputStreamReader(is);//把字节流转成字符流
46         BufferedReader br = new BufferedReader(isr);
47         String result = br.readLine();
48         System.out.println(result);
49
50         //(5)关闭
51         fis.close();
52         input.close();
53         socket.close();
54     }
55 }

  服务器端的示例代码:

 1 import java.net.ServerSocket;
 2 import java.net.Socket;
 3
 4 public class Server {
 5     public static void main(String[] args) throws Exception{
 6         //服务器在8888端口号监听数据
 7         @SuppressWarnings("resource")
 8         ServerSocket server = new ServerSocket(8888);
 9
10         while(true){
11             //(2)等待连接
12             //这句代码执行一次,意味着一个客户端连接
13             Socket accept = server.accept();
14
15             FileUploadThread ft = new FileUploadThread(accept);
16             ft.start();
17         }
18     }
19 }

  服务器端处理每一个客户端上传文件的线程类代码:

 1 import java.io.DataInputStream;
 2 import java.io.FileNotFoundException;
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.io.OutputStream;
 7 import java.io.PrintStream;
 8 import java.net.Socket;
 9 import java.text.SimpleDateFormat;
10 import java.util.Date;
11
12 public class FileUploadThread extends Thread{
13     private Socket socket;
14     private String dir = "upload/";
15
16     public FileUploadThread(Socket socket) {
17         super();
18         this.socket = socket;
19     }
20
21     public void run(){
22         FileOutputStream fos = null;
23         try {
24             InputStream is = socket.getInputStream();
25             DataInputStream dis = new DataInputStream(is);
26
27             //读取文件名(含后缀名)
28             String filename = dis.readUTF();
29             //截取后缀名
30             String ext = filename.substring(filename.lastIndexOf("."));
31             //生成时间戳
32             SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
33             filename = sf.format(new Date());
34             //用新文件路径构建文件输出流
35             fos = new FileOutputStream(dir + filename + ext);
36             //接收文件内容
37             byte[] data = new byte[1024];
38             while(true){
39                 int len = is.read(data);
40                 if(len==-1){
41                     break;
42                 }
43                 fos.write(data, 0, len);
44             }
45
46             //返回结果
47             OutputStream out = socket.getOutputStream();
48             PrintStream ps = new PrintStream(out);
49             ps.println(filename + ext + ":已上传完毕");
50         } catch (FileNotFoundException e) {
51             e.printStackTrace();
52         } catch (IOException e) {
53             e.printStackTrace();
54         }finally{
55             try {
56                 fos.close();
57                 socket.close();
58             } catch (IOException e) {
59                 e.printStackTrace();
60             }
61         }
62     }
63 }

原文地址:https://www.cnblogs.com/niujifei/p/12291766.html

时间: 2024-10-09 06:38:56

Java 网络编程案例三:多个客户端上传文件的相关文章

黑马程序员 【】java学习之路——TCP(三)客户端上传文件到服务器

------- <a href="http://www.itheima.com" target="blank">android培训</a>.<a href="http://www.itheima.com" target="blank">java培训</a>.期待与您交流! ---------- import java.io.*; import java.net.*; class

asp.net 客户端上传文件全路径获取方法

asp.net  获取客户端上传文件全路径方法: eg:F:\test\1.doc 基于浏览器安全问题,浏览器将屏蔽获取客户端文件全路径的方法,只能获取到文件的文件名,如果需要获取全路径则需要另想其他方法 如下提供两种方法: 方法1:工具 -> Internet选项 -> 安全 -> 自定义级别 -> 找到“其他”中的“将本地文件上载至服务器时包含本地目录路径”,选中“启用”即可. 方法2: function getPath() { //获取file 控件对象 var obj =

LightSwitch Picture File Manager LS HTML 客户端上传文件

LightSwitch Picture File Manager   LS HTML 客户端上传文件: http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/157/A-Visual-Studio-LightSwitch-Picture-File-Manager.aspx LightSwitch Picture File Manager LS HTML 客户端上传文件

java 网络编程(三)---TCP的基础级示例

下面是TCP java网络编程的基础示例: tcp传输:客户端建立过程的思路:1.创建TCP客户端的Socket服务,使用的是socket对象,建议在创建的过程中,就明确了目的地和要连接的主机2.如果连接建立成功,说明数据传输通道已经建立,该通道就是Socket的I/O流,是底层建立好的,既然是流,就说明有输入流,就有输出流,要换取就找socket获取相关的流即可,   getInputStream()和getOutputStream()的字节流.3.使用输出流,将数据输出:使用输入流,把数据输

iOS开发之网络编程--5、NSURLSessionUploadTask+NSURLSessionDataDelegate代理上传

前言:关于NSURLSession的主要内容快到尾声了,这里就讲讲文件上传.关于文件上传当然就要使用NSURLSessionUploadTask,这里直接讲解常用的会和代理NSURLSessionDataDelegate一起搭配实现文件上传功能.另外,下面使用的文件上传思路是和NSURLConnection中本人之前的随笔<iOS开发之网络编程--使用NSURLConnection实现文件上传>提到的上传思路是一样的,都是要将请求信息拼接起来,然后传入到请求里进行上传.这个拼接过程是必要的,但

Java网络编程案例---聊天室

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net包中JavaSE的API包含有类和接口,它们提供低层次的通信细节.你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节. java.net包中提供了两种常见的网络协议的支持: TCP:TCP是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信.通常用于互联网协议,被称TCP/IP. UDP:UDP是用户数据报协议的缩写,一个无连接的协议.提供了应用程序之间要发送的数据的数据报. 本案例以

Java 网络编程(三) 创建和使用URL访问网络上的资源

链接地址:http://www.cnblogs.com/mengdd/archive/2013/03/09/2951877.html 创建和使用URL访问网络上的资源 URL(Uniform Resource Locator)是统一资源定位符的简称,它表示Internet上某一资源的地址. 通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW, FTP站点.浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源. 在目前使用最为广泛的TCP/IP中对于URL中主机名

多个客户端上传文件

TCP使用中的多线程问题 1.问题:一般的TCP程序在处理多线程情况时会出现问题: 如:有A.B两个客户端向服务器发送数据,当A客户端连接上以后被服务端获取到,服务端执行具体流程:这时B客户端连接,只有等待. 因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法.所以暂时获取不到B客户端对象. 2.解决思路: 服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求. 程序代码: 客户端: 1 class PicSend{ 2 3 public

12.5-全栈Java笔记:Java网络编程(三)

上节回顾:在学习了Socket在建立客户端和服务器单项通讯中,分别创建独立的Socket,并通过Socket的属性. 那么如何将两个Socket进行连接,从而达到客户端和服务器之间建立输入输出流进行通信呢?在上节中我们已经讲到,TCP/IP套接字是最可靠的双向流协议,使用TCP/IP可以发送任意数量的数据.如果发送方和接收方计算机确定好端口,他们就可以通信了,其中的端口用套接字表示. [示例1]客户端与服务器端双向交流的Socket之服务器端 import java.io.BufferedRea