TCP 实现文件上传(单线程实现和多线程实现)

文件的上传需要保证数据的安全性、完成性以及连接性,所以使用 TCP 协议来实现,这里就以上传一张图片文件为例,分别使用单线程和多线程来实现,单线程就是一个服务器接收一个客户端发来的图片,多线程就是一个服务器同时接收多个客户端发来的图片。

一、单线程实现

(1) 客户端实现:

  1. Socket 套接字连接服务器
  2. 通过 Socket 获取字节输出流,进行写图片
  3. 使用自己的流对象读取图片流资源
  4. 读取图片,使用字节输出流将图片写到服务器,采用字节数组进行缓冲
  5. 通过 Socket 套接字获取字节输入流
  6. 获取服务器端的反馈回来的信息
  7. 关闭流资源
/**
 * 客户端实现
 * 1、Socket 套接字连接服务器
 * 2、通过 Socket 获取字节输出流,进行写图片
 * 3、使用字节流对象读取图片流资源
 * 4、读取图片,使用字节输出流将图片写到服务器,采用字节数组进行缓冲
 * 5、通过 Socket 套接字获取字节输入流
 * 6、获取服务器端的反馈回来的信息
 * 7、关闭流资源
 */
public static void main(String[] args) throws IOException {
    //1、Socket 套接字连接服务器
    Socket socket = new Socket(InetAddress.getLocalHost().getHostAddress(),8888);
    //2、通过 Socket 获取字节输出流,进行写图片
    OutputStream OS = socket.getOutputStream();
    //3、使用字节流对象读取图片流资源
    FileInputStream FIS = new FileInputStream("F:\\De-lovely\\LR_Mountain_Hand.jpg");
    //4、读取图片,使用字节输出流将图片写到服务器,采用字节数组进行缓冲\
    int length;
    byte[] bytes = new byte[1024];
    while ((length = FIS.read(bytes)) != -1)
    {
        //5、通过 Socket 套接字获取字节输入流
        OS.write(bytes,0,length);
    }
    //给服务器写终止序列
    socket.shutdownOutput();
    //6、获取服务器端的反馈回来的信息
    InputStream IS = socket.getInputStream();
    length = IS.read(bytes);
    System.out.println(new String(bytes,0,length));
    //7、关闭流资源
    FIS.close();
    socket.close();
}

(2) 服务器实现

  1. 创建 ServerSocket 套接字对象,监听端口
  2. accept() 方法获取客户端的连接对象
  3. 客户端连接对象获取字节输入流,读取客户端发送的图片
  4. 创建 File 对象,绑定上传文件夹
  5. 创建字节输出流
  6. 字节流得到图片,将图片写进写到文件夹中
  7. 发送消息给客户端
  8. 关闭流资源
/**
 * 服务器实现
 * 1、创建 ServerSocket 套接字对象,监听端口
 * 2、accept() 方法获取客户端的连接对象
 * 3、客户端连接对象获取字节输入流,读取客户端发送的图片
 * 4、创建 File 对象,绑定上传文件夹
 * 5、创建字节输出流
 * 6、字节流得到图片,将图片写进写到文件夹中
 * 7、发送消息给客户端
 * 8、关闭流资源
 */
public static void main(String[] args) throws IOException {
    //1、创建 ServerSocket 套接字对象,监听端口
    ServerSocket ser = new ServerSocket(8888);
    //2、accept() 方法获取客户端的连接对象
    Socket soc = ser.accept();
    //3、客户端连接对象获取字节输入流,读取客户端发送的图片
    InputStream IS = soc.getInputStream();
    //4、创建 File 对象,绑定上传文件夹
    String FileName = "Love" + System.currentTimeMillis() + new Random().nextInt(999999)+ ".jpg";
    BufferedOutputStream BOS = new BufferedOutputStream(new FileOutputStream("C:\\Users\\OneStar\\Desktop\\"+FileName));
    //5、创建字节输出流
    byte[] bytes = new byte[1024];
    int length;
    //6、字节流得到图片,将图片写进写到文件夹中
    while ((length = IS.read(bytes)) != -1)
    {
        BOS.write(bytes,0,length);
    }
    //7、发送消息给客户端
    OutputStream OS = soc.getOutputStream();
    OS.write("图片上传成功!".getBytes());
    OS.flush();
    //8、关闭流资源
    soc.close();
    BOS.close();
    OS.close();
}

二、多线程实现

多线程实现文件上传只要修改服务器代码即可,修改如下

//在main中创建线程
public static void main(String[] args) throws IOException {
    //1、创建 ServerSocket 套接字对象,监听端口
    ServerSocket SS = new ServerSocket(8888);
    while (true)
    {
        //2、获取到一个客户端就开启一个新线程
        Socket soc = SS.accept();
        Upload load = new Upload(soc);
        Thread T1 = new Thread(load);
        T1.start();
    }
}
//在Upload类中实现Runable接口,重写run方法
public class Upload implements Runnable {
    private Socket soc;
    public Upload(Socket soc){
        this.soc = soc;
    }
    public void run() {
        try {
            //3、客户端连接对象获取字节输入流,读取客户端发送的图片
            InputStream IS = soc.getInputStream();
            //4、创建 File 对象,绑定上传文件夹
            String FileName = "Love" + System.currentTimeMillis() + new Random().nextInt(999999) + ".jpg";
            BufferedOutputStream BOS = new BufferedOutputStream(new FileOutputStream("C:\\Users\\OneStar\\Desktop\\" + FileName));
            //5、创建字节输出流
            byte[] bytes = new byte[1024];
            int length;
            //6、字节流得到图片,将图片写进写到文件夹中
            while ((length = IS.read(bytes)) != -1) {
                BOS.write(bytes, 0, length);
            }
            //7、发送消息给客户端
            OutputStream OS = soc.getOutputStream();
            OS.write("图片上传成功!".getBytes());
            OS.flush();
            //8、关闭流资源
            BOS.close();
            OS.close();
        }
        catch (Exception e){
        }
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ONESTAR博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值