跨服务器文件上传,socket文件上传

1.功能说明:提供一个对外的接口,能够跨域通过该接口把文件上传到提供服务的服务器。

     例如:有A,B两个服务器,A服务器提供一个接口,B服务器可以通过该接口和A服务器进行数据交互。如文件上传(包括文件名),传string消息等等

2.使用技术:socket

3.目录

 3.1.基础版本:文件上传

 3.2.获取文件名:获取上传的名称

 3.3.线程池文件上传

3.1基础版本

1.客户端代码
复制代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class clientString {
public static void main(String[] args) throws UnknownHostException, IOException {
  //1.创建一个客户端对象socket,构造方法绑定服务器的Ip地址和端口号
  Socket socket = new Socket("127.0.0.1",8080);
  //2.使用socket对象中的方法getOutpustream()获取网络字节输出流outputstream对象
  OutputStream os=socket.getOutputStream();
  //3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
  os.write("你好服务器".getBytes());
 
  //4.使用Socket 对象中的方法getInputstream()获取网络字节输入流InputStream对象
  InputStream is = socket.getInputStream();
  //5.使用网络字节输入流inpustream对象中的方法read,读取服务器回写的数据
  byte[] readBuff=new byte[1024];
  int length=is.read(readBuff);
  String message=new String(readBuff,0,length);
  //6.释放资源
  socket.close();
  System.out.println("服务器的响应内容:"+message);
  }
}
复制代码

 

2.服务端代码
复制代码
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class serviceString {
  private static final int PORT =8080;
  public static void main(String[] args) {
    System.out.println("服务器已经启动");
    try {
    //1.创建服务器serverSocket对象和系统要指定的端口号
    ServerSocket server= new ServerSocket(PORT);
    //2.使用Server Socket对象中的方法accept,获取请求的客户端对象Socket
    Socket socket = server.accept();
 
    //3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
    InputStream is=socket.getInputStream();
    //4.使用网络字节输入流Input Stream对象中的方法read,读取客户端发送的数据
    byte[] bytes=new byte[1024];
    int len = is.read(bytes);
    System.out.println(new String(bytes,0,len));
    //5.使用Socket对象中的方法getOutputStream()获取网络字节输出流Output Stream对象
    OutputStream os=socket.getOutputStream();
    //6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
    os.write("收到谢谢".getBytes());
    //7.释放资源
    socket.close();
    server.close();
 
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println("服务器关闭");
  }
}
复制代码

3.2.获取上传文件的名称

服务端

复制代码
package outService;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
public class serviceMangThread {
    private static final int PORT =8080;
    public static void main(String[] args) {
        System.out.println("服务器已经启动");
        try {
            //1.创建服务器serverSocket对象和系统要指定的端口号
            ServerSocket server= new ServerSocket(PORT);
            //升级:外部可以一直调用,而不是调用一次之后就结束
            while(true) {
                //2.使用Server Socket对象中的方法accept,获取请求的客户端对象Socket
                Socket socket = server.accept();
                //升级:使用多线程,提高效率,有一个客户端上传文件,就开启一个线程,完成文件的上传
                new Thread(new Runnable() {
                    //完成文件的上传
                    @Override
                    public void run() {
                        try{
                            //3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
                            InputStream is=socket.getInputStream();
                            
                            //重点:start
                            //使用DataInputStream包装输入流
                            DataInputStream dataInputStream = new DataInputStream(is);
                            String fileNames = dataInputStream.readUTF();//获取传递过来的文件名
                            System.out.println(fileNames);//在控制台显示文件名
                            //重点:end
                            
                            //4.判断d:\\upload文件夹是否存在,不存在则创建
                            File file =new File("C:\\Users\\doume\\Desktop\\图片\\test");
                            if(!file.exists()) {
                                file.mkdirs();
                            }
                            String fileName =fileNames+".mp4";
                            
                            //5.使用Socket对象中的方法getOutputStream()获取网络字节输出流Output Stream对象
                            FileOutputStream fos = new FileOutputStream(file+"\\"+fileName);
                            
                            //6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
                            int length=0;
                            byte[] buff=new byte[1024];
                            while((length=is.read(buff))!=-1) {
                                //7.使用本地字节输出流FileOutputStream 对象中的方法write,把读取到的文件保存到服务器的
                                fos.write(buff,0,length);
                            }
                            System.out.println("文件上传到:"+file+"\\"+fileName);
                            //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
                            //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写“上传成功”
                            socket.getOutputStream().write("上传成功".getBytes());
                            //10.释放资源(FileOutputStream,Socket,ServerSocket)
                            fos.close();
                            socket.close();
                        }catch (IOException e) {
                            e.printStackTrace();
                            System.out.println("对外视频文件上传出错");
                        }
                    }
                }).start();
                
                
            }
            
            //升级:服务器不用关闭了
            //server.close();
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("服务器关闭");
    }

}
复制代码

 

客户端

复制代码
package outSlient;

import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class clientMangThread {
    /*
     * TCP通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据
      *  表示客户端的类:
     *  Java.net.Socket:此类实现客户端套字节。套字节是两台机器间通信的端点,套字节包含了IP地址和端口号的网络单位
      *  构造方法:
     *     socket(String host,int port)创建一个流套接字并将其连接到指定的主机上的指定端口号
     *     参数:
     *         String host:服务器主机的名称/服务器的IP地址
     *         int port :服务器的端口号
      *  成员方法:
     *     OutputStream getOutStream() 返回此套接字的输出流
     *  InputStream getInputStream() 返回此套接字的输出流
     *  void close() 关闭此套接字
      * 实现步骤:
     * 1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
     * 2.使用Socket对象中的方法getOutputStrleam()获取网络字节输出流OutputStream对象
     * 3.使用网络字节输出流outputStream对象中的方法write,给服务器发送数据
     * 4.使用Socket对象中的方法getInputStream()获取字节输入流InputStream对象
     * 5.使用网络字节输入流Input Stream对象中的方法read,读取服务器回写的数据
     * 6.释放资源(Socket)
     * 
     * 注意:
     * 1.客户端和服务端进行交流,必须使用Socket中提供的网络流,不能使用自己创建的流对象
     * 2.当我们创建客户端对象Socket的时候,就会去请求服务器并和服务器经过三次握手建立连接通过,
     *   这时如果服务器没有启动,那么就会抛出异常,如果服务器已经启动,那么就可以进行交互了
     */
    
    //要请求的服务的地址和端口号
    private static final String IP="127.0.0.1";
    private static String filePath = "C:\\Users\\doume\\Desktop\\图片\\视频\\范彬彬.mp4";
    private static final int PORT =8080;
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        System.out.println("我要把图片上传到服务器:"+IP);
        try {
            //建立连接
            Socket socket=new Socket(IP,PORT);
            //读取图像文件上传
            FileInputStream fis=new FileInputStream(filePath);
            OutputStream os=socket.getOutputStream();
            
            String fileName="范彬彬.mp4";
            //重点:start
            //向服务器端传文件名
            DataOutputStream dataOutputStream = new DataOutputStream(os);
            dataOutputStream.writeUTF(fileName);
            dataOutputStream.flush();//刷新流,传输到服务端
            //重点:end
            
            byte[] buff=new byte[1024*1024];
            int length=0;
            
            while((length=fis.read(buff))!=-1) {
                os.write(buff,0,length);
            }
            socket.shutdownOutput();
            
            //读取响应的数据
            InputStream is = socket.getInputStream();
            byte[] readBuff=new byte[1024];
            length=is.read(readBuff);
            String message=new String(readBuff,0,length);
            
            System.out.println("服务器的响应结束:"+message);
            
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
}
复制代码

 3.3 线程池文件上传

客户端

复制代码
package outSlient;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

public class clientMangThread {
    /*
     * TCP通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据
      *  表示客户端的类:
     *  Java.net.Socket:此类实现客户端套字节。套字节是两台机器间通信的端点,套字节包含了IP地址和端口号的网络单位
      *  构造方法:
     *     socket(String host,int port)创建一个流套接字并将其连接到指定的主机上的指定端口号
     *     参数:
     *         String host:服务器主机的名称/服务器的IP地址
     *         int port :服务器的端口号
      *  成员方法:
     *     OutputStream getOutStream() 返回此套接字的输出流
     *  InputStream getInputStream() 返回此套接字的输出流
     *  void close() 关闭此套接字
      * 实现步骤:
     * 1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
     * 2.使用Socket对象中的方法getOutputStrleam()获取网络字节输出流OutputStream对象
     * 3.使用网络字节输出流outputStream对象中的方法write,给服务器发送数据
     * 4.使用Socket对象中的方法getInputStream()获取字节输入流InputStream对象
     * 5.使用网络字节输入流Input Stream对象中的方法read,读取服务器回写的数据
     * 6.释放资源(Socket)
     * 
     * 注意:
     * 1.客户端和服务端进行交流,必须使用Socket中提供的网络流,不能使用自己创建的流对象
     * 2.当我们创建客户端对象Socket的时候,就会去请求服务器并和服务器经过三次握手建立连接通过,
     *   这时如果服务器没有启动,那么就会抛出异常,如果服务器已经启动,那么就可以进行交互了
     */
    
    //要请求的服务的地址和端口号
    private static final String IP="127.0.0.1";
    private static String filePath = "C:\\Users\\doume\\Desktop\\图片\\视频\\范彬彬.mp4";
    private static final int PORT =8080;
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        System.out.println("我要把图片上传到服务器:"+IP);
        try {
            //建立连接
            Socket socket=new Socket(IP,PORT);
            //读取图像文件上传
            FileInputStream fis=new FileInputStream(filePath);
            OutputStream os=socket.getOutputStream();
            
            String fileName="范彬彬";
            //重点:start
            //向服务器端传文件名
            DataOutputStream dataOutputStream = new DataOutputStream(os);
            dataOutputStream.writeUTF(fileName);
            dataOutputStream.flush();//刷新流,传输到服务端
            //重点:end
            
            byte[] buff=new byte[1024*1024];
            int length=0;
            
            while((length=fis.read(buff))!=-1) {
                os.write(buff,0,length);
            }
            socket.shutdownOutput();
            
            //读取响应的数据
            InputStream is = socket.getInputStream();
            byte[] readBuff=new byte[1024];
            length=is.read(readBuff);
            String message=new String(readBuff,0,length,StandardCharsets.UTF_8);
            System.out.println("服务器的响应结束:"+message);
            
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
复制代码

服务端

复制代码
package outService;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class serviceMangThread {
    private static final int PORT =8080;
    public static void main(String[] args) {
        System.out.println("服务器已经启动hahha");
        ThreadPoolExecutor service = new ThreadPoolExecutor(5, 200,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        try {
            //1.创建服务器serverSocket对象和系统要指定的端口号
            ServerSocket server= new ServerSocket(PORT);
            //升级:外部可以一直调用,而不是调用一次之后就结束
            while(true) {
                //2.使用Server Socket对象中的方法accept,获取请求的客户端对象Socket
                Socket socket = server.accept();
                // 等待执行的runnable
                Runnable runnable = () -> {
                    try{
                        //3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
                        InputStream is=socket.getInputStream();

                        //重点:start
                        //使用DataInputStream包装输入流
                        DataInputStream dataInputStream = new DataInputStream(is);
                        String fileNames = dataInputStream.readUTF();//获取传递过来的文件名
                        System.out.println(fileNames);//在控制台显示文件名
                        //重点:end

                        //4.判断d:\\upload文件夹是否存在,不存在则创建
                        File file =new File("C:\\Users\\doume\\Desktop\\图片\\test");
                        if(!file.exists()) {
                            file.mkdirs();
                        }
                        //升级:防止文件重复
                        String fileName =System.currentTimeMillis()+new Random(99999).nextInt()+".mp4";

                        //5.使用Socket对象中的方法getOutputStream()获取网络字节输出流Output Stream对象
                        FileOutputStream fos = new FileOutputStream(file+"\\"+fileName);

                        //6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
                        int length = 0;
                        byte[] buff=new byte[1024];
                        while((length=is.read(buff))!=-1) {
                            //7.使用本地字节输出流FileOutputStream 对象中的方法write,把读取到的文件保存到服务器的
                            fos.write(buff,0,length);
                        }
                        System.out.println("文件上传到:"+file+"\\"+fileName);
                        //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
                        //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写“上传成功”
                        socket.getOutputStream().write("上传成功".getBytes());
                        //10.释放资源(FileOutputStream,Socket,ServerSocket)
                        fos.close();
                        socket.close();
                    }catch (IOException e) {
                        e.printStackTrace();
                        System.out.println("对外视频文件上传出错");
                    }
                };
                service.execute(runnable);

                /*// 监控线程池执行情况的代码
                ThreadPoolExecutor tpe = ((ThreadPoolExecutor) service);
                while (true) {
                    System.out.println();

                    int queueSize = tpe.getQueue().size();
                    System.out.println("当前排队线程数:" + queueSize);

                    int activeCount = tpe.getActiveCount();
                    System.out.println("当前活动线程数:" + activeCount);

                    long completedTaskCount = tpe.getCompletedTaskCount();
                    System.out.println("执行完成线程数:" + completedTaskCount);

                    long taskCount = tpe.getTaskCount();
                    System.out.println("总线程数:" + taskCount);

                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }*/
            }

            //升级:服务器不用关闭了
            //server.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("服务器关闭");
    }

}
复制代码

 

 

 

posted @   王短腿  阅读(343)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示