• Java 学习笔记 网络编程 使用Socket传输文件 CS模式


    Socket的简单认识

    Socket是一种面向连接的通信协议,Socket应用程序是一种C/S(Client端/Server端)结构的应用程序
    Socket是两台机器间通信的端点。
    Socket是连接运行在网络上的两个程序间的双向通讯端点。

    Socket通信原理

    • Server服务端的输入流相当于Client客户端的输出流
    • Server服务端的输出流相当于Client客户端的输入流

    注意

    • 文件传输使用字节流(Steam)
    • 使用DataOutputStream,DataOutputStream可以传java的基本类型和流

    代码

    Server.java

    package csmode2;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     * @author StarsOne
     * @date Create in  2019-4-14 0014 10:53:58
     * @description
     */
    class Server {
        public static void main(String[] args) {
            try (ServerSocket serverSocket = new ServerSocket(9090)){
    
                System.out.println("服务器已启动...");
                
                while (true) {
                    System.out.println("等待接收文件");
                    //调用了accept方法之后,会一直处于等待接受文件的状态
                    Socket socket = serverSocket.accept();//接收客户端传来的数据
                    //交给后台线程处理
                    new AcceptThread(socket.getInputStream()).start();
                }
    
    
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }
    
    

    AcceptThread.java

    package csmode2;
    
    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * @author StarsOne
     * @date Create in  2019/4/15 0015 14:17
     * @description
     */
    class AcceptThread extends Thread {
        private InputStream inputStream;
    
        public AcceptThread(InputStream inputStream) {
            this.inputStream = inputStream;
        }
    
        @Override
        public void run() {
            try {
                //使用DataInputStream包装输入流
                DataInputStream dataInputStream = new DataInputStream(inputStream);
    
                String fileName = dataInputStream.readUTF();
                System.out.println(fileName);//在控制台显示文件名
    
                //往某个位置写入文件
                FileOutputStream fileOutputStream = new FileOutputStream("Q:\MY" + File.separator + fileName);
                int c = -1;
                while ((c = dataInputStream.read()) != -1) {
                    fileOutputStream.write(c);
                    fileOutputStream.flush();
                }
    
                System.out.println("文件上传成功!");
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    Client.java

    package csmode2;
    
    import java.io.*;
    import java.net.Socket;
    
    /**
     * @author StarsOne
     * @date Create in  2019-4-14 0014 10:53:49
     * @description
     */
    class Client {
        public static void main(String[] args) {
            //        File[] files = new File("E:\wan\testfile").listFiles();
            //如果是多个文件,只需要把文件放入一个list或者数组中,使用for循环把数组的文件全部上传到服务器
    
            //上传的文件
            File file = new File("R:\动漫图片\test.jpg");
    
            try(Socket socket = new Socket("localhost", 9090)) {
    
                OutputStream outputStream = socket.getOutputStream();
                //使用DataOutputStream
                DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
                //向服务器端传文件名
                dataOutputStream.writeUTF(file.getName());
                dataOutputStream.flush();//刷新流,传输到服务端
    
                //向服务器端传文件,通过字节流
                //字节流先读取硬盘文件
                BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
                
                int c = -1;
                while ((c=bufferedInputStream.read())!=-1) {
                    //将读取的文件以字节方式写入DataOutputStream,之后传输到服务端
                    //这里也可以使用byte[]数据进行读取和写入
                    dataOutputStream.write(c);
                    dataOutputStream.flush();
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
  • 相关阅读:
    js公共时间戳方法es6
    vue权限路由
    vue中websocket心跳写法
    vue引入全局组件和局部组件的区别以及全局注册公共函数
    [干货]关于vue作用域插槽的新的深入理解
    vue系统指令v-text(前端网备份)
    浏览器兼容html头部<meta>标签主要内容详情
    如何设置td中溢出内容的隐藏显示
    7-4列表/元组/字典/集合的内置方法
    7-3 整型/浮点型/字符串/列表常用方法
  • 原文地址:https://www.cnblogs.com/stars-one/p/10712415.html
Copyright © 2020-2023  润新知