04-socket项目练习-文件(图片)上传

课题分析:客户端读取本地硬盘文件,把文件传给服务器,服务器再把上传的文件保存到服务器的硬盘上。

实现步骤分析:

1.客户端使用本地字节输入流,读取本地硬盘上的问件;

2.客户端使用网络字节输出流,把读取的文件上传到服务器;

3.服务器端使用网络字节输入流,读取客户端上传的文件

4.服务器端使用本地字节输出流,将客户端的文件保存至服务器硬盘

5.服务器端使用网络字节输出流,向客户端传递"上传成功"信息

6.客户端使用网络字节输入流,收到来自服务器端的回信

7.释放资源

具体实现:

客户端实现:

具体实现步骤:

1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的资源

2.创建一个客户端对象Socket,构造方法绑定服务器的IP地址以及端口号

3.使用Socket对象的getOutputStream()获取网络字节输出流OutputStream对象

4.使用本地字节输入流FileInputStream对象中的read(),读取本地文件

5.使用OutputStream对象的write(),给服务器发送数据

6.使用Socket对象的getInputStream() 获取网络字节输入流InputStream对象

7.使用InputStream对象的read(),读取服务器回写的数据

8.释放资源(FileInputStream   Socket)

package com.socket.filesocket;

import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args)  {
        try {
            //1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的资源
            FileInputStream fis= new FileInputStream("d:\1.jpg");
            //2.创建一个客户端对象Socket,构造方法绑定服务器的IP地址以及端口号
            Socket client=new Socket("127.0.0.1",8888);
            //3.使用Socket对象的getOutputStream()获取网络字节输出流OutputStream对象
            OutputStream os= client.getOutputStream();
            //4.使用本地字节输入流FileInputStream对象中的read(),读取本地文件
            int len=0;
            byte[] bytes=new byte[1024];
            while((len=fis.read(bytes))!=-1){
                //5.使用OutputStream对象的write(),给服务器发送数据
                os.write(bytes,0,len);
            }
            System.out.println("文件以传送");
            client.shutdownOutput();
            //6.使用Socket对象的getInputStream() 获取网络字节输入流InputStream对象
            InputStream is=   client.getInputStream();
            //7.使用InputStream对象的read(),读取服务器回写的数据
            while((len=is.read(bytes))!=-1){
                //5.使用OutputStream对象的write(),给服务器发送数据
                System.out.println(new String(bytes,0,len));
            }
            //8.释放资源(FileInputStream   Socket)
            fis.close();
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务器端实现:

具体实现步骤:

1.创建服务器ServerSocket对象和系统要指定的端口号

2.使用ServerSocket的accept(),获取到请求的客户端对象Socket

3.使用Socket对象的getInputStream() 获取网络字节输入流InputStream对象

4.判断d:\iotest文件夹是否存在,不存在的话就创建一个

5.创建一个本地字节输出流FileOutputStream,构造方法中绑定要输出的目的地

6.使用InputStream对象的read(),读取客户端发送的的数据

7.使用本地数据输出流FileOutputStream对象的write(),把读取的文件保存到服务器的硬盘上

8.使用Socket对象的getOutputStream()获取网络字节输出流OutputStream对象

9.使用OutputStream对象的write(),给服务器发送"上传成功"

10.释放资源(Socket  FileOutputStream    ServerSocket)

注:以下代码为服务器端优化过代码

优化说明:1.对服务器保存至硬盘的图片名称进行了优化,修改为了:域名+毫秒值+随机数

2.将服务器进行了长时间监听,服务器的socket未关闭

3.为了提高多次上传的效率,将图片保存的步骤放入了多线程

package com.socket.filesocket;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

public class Server {
    public static void main(String[] args) throws IOException {
            //1.创建服务器ServerSocket对象和系统要指定的端口号
            ServerSocket serverSocket=new ServerSocket(8888);
            System.out.println("服务器端开启。。。请打开客户端连接");
            //2.使用ServerSocket的accept(),获取到请求的客户端对象Socket
            /*
            优化:让服务器一直处于监听状态(使accept死循环)
            有一个客户端上传文件,就保存一个
            */
            while (true){
                Socket server=serverSocket.accept();
                /*
                优化:当多台客户端去上传文件时,服务器的效率会降低
                采用多线程,提高效率
                一个客户端,开启一个线程
                */
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            //3.使用Socket对象的getInputStream() 获取网络字节输入流InputStream对象
                            InputStream is=server.getInputStream();
                            //4.判断d:\iotest文件夹是否存在,不存在的话就创建一个
                            File file=new File("d:\iotest");
                            if(!file.exists()){
                                file.mkdirs();
                            }
                        /*
                        自定义文件名,防止文件名相同形成覆盖
                        规则:域名+毫秒值+随机数
                        */
                            String filename="itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";
                            //5.创建一个本地字节输出流FileOutputStream,构造方法中绑定要输出的目的地
                            FileOutputStream fos=new FileOutputStream(file+"\"+filename);
                            //6.使用InputStream对象的read(),读取客户端发送的的数据
                            int len=0;
                            byte[] bytes=new byte[1024];
                            while((len=is.read(bytes))!=-1){
                                //7.使用本地数据输出流FileOutputStream对象的write(),把读取的文件保存到服务器的硬盘上
                                fos.write(bytes,0,len);
                            }
                            //8.使用Socket对象的getOutputStream()获取网络字节输出流OutputStream对象
                            //9.使用OutputStream对象的write(),给服务器发送"上传成功"
                            server.getOutputStream().write("上传成功".getBytes());
                            //10.释放资源(Socket  FileOutputStream    ServerSocket)
                            fos.close();
                            server.close();
                        }catch(IOException e){
                            e.printStackTrace();
                        }
                    }
                }).start();
         }
    }
}
原文地址:https://www.cnblogs.com/rongrui/p/13979066.html