跨服务器文件上传,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("服务器关闭"); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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)