• 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();
             }
        }
    }
  • 相关阅读:
    CodeForces1422A
    C++
    2020第十一届蓝桥杯第一场 B组 C/C++
    Aizu0118
    POJ1979
    monkey 稳定性测试
    adb shell 杀进程以及端口占用,adbserver服务重启失败
    windows查询端口,杀进程
    apk 测试入门基本操作
    解决 genymotion 安装apk报错 app contains ARM native code and your Genymotion device cannot run ARM instructions
  • 原文地址:https://www.cnblogs.com/rongrui/p/13979066.html
Copyright © 2020-2023  润新知