java利用socket套接字和io流以及多线程在网络上下载文件和上传文件

本文介绍了一个简单的文件传输系统实现,包括客户端和服务端的交互过程。服务端通过多线程方式为客户端提供文件下载服务,并能够接收客户端上传的文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从服务端下载文件

首先我们先做一下服务端

/**
 * 服务端:给客户端提供服务
 * 1.接收客户端发送过来的文件路径,并判断文件是否存在
 * 2.获取文件的名称和文件的长度,并写到网络上
 * 3.从本服务器硬盘读取文件内容到内存
 * 4.把内存的文件数据写到网络上
 * 
 * 多线程可以给多个客户端提供服务
 * @author PC
 *
 */
public class Server {
	public static void main(String[] args)throws Exception {
	   ServerSocket ss=new ServerSocket(8888);//端口为8888
	   while(true){
         Socket socket=ss. accept();
         ThreadHandler th=new THreadHandler(socket);//业务逻辑
           Thread t=new Thread(th);
           t.start();
      }
	}
	}
	接下来我们作一下业务逻辑:
	/**
 * 这个run任务逻辑,要给很多个socket提供服务
 * @author PC
 *
 */
public class ThreadHandler implements Runnable {
    private Socket socket;
    public ThreadHandler(Socket socket){
    	this.socket=socket;
    }
	@Override
	public void run() {
		 try {
			 //获取网络ip地址
			 InetAddress ip=socket.getInetAddress();
			//构建网络输入输出流
			//网络输出流
			OutputStream os=socket.getOutputStream();
			BufferedOutputStream bos=new BufferedOutputStream(os);
			DataOutputStream dos=new DataOutputStream(bos); 
			//构建输入流
			DataInputStream dis=new DataInputStream(new BufferedInputStream(socket.getInputStream()));
			
			String filePath=dis.readUTF();
            File file=new File(filePath);
            if(!file.exists()){
            	dos.writeUTF("你请求的文件不在服务器中,请换其他的文件路径");
            	dos.flush();
            	return;
            }
            //能到此处,说明文件存在
            //获取文件的名称和长度
            String fileName=file.getName();
            dos.writeUTF(fileName);
            dos.flush();
            //获取文件的长度
            long length=file.length();
            dos.writeUTF(length+"");
            dos.flush();
            //准备开始发送文件
            System.out.println(ip.getHostAddress()+"        fileName="+fileName+"    length="+length);
            System.out.println(ip.getHostAddress()+"  开始发送文件...");
            //从本地读取文件到内存中(本地流)
            DataInputStream dis_local=new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
            byte[] buffer=new byte[1024*4];
            while(true){
            	int len=-1;
            			
            	if(dis_local!=null){
            		//本地流输入
            		len=dis_local.read(buffer);
            	}
            	if(len==-1){
            		break;
            	}
            	dos.write(buffer,0,len);
            }

			dos.flush();//清除缓冲,标记数据写出完毕,此时才将数据发送到网络上
			dos.close();
			bos.close();
			os.close();
			dis.close();
			dis_local.close();
			//关闭套接字
			socket.close();
			System.out.println(ip.getHostAddress()+"  文件:"+fileName+"发送完毕");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
客户端可以通过8888端口和服务器的地址与服务器进行套结;

/**
 * 客户端:
 * 1.连接服务端
 * 2.从键盘输入服务端的计算机中的文件路径,并请求下载
 * 3.如果服务端有文件,就返回给客户端文件的名称和长度
 * 4.从网络上获取服务端下载的文件数据进入客户端的内存
 * 5.把内存的数据写到客户端的硬盘上
 * 
 * @author PC
 *
 */
public class Client {
	public static void main(String[] args)throws Exception {
     Scanner input =new Scanner(System.in);
     //创建Socket对象(Ip地址,端口号),相当于连接服务器
     Socket socket=new Socket("服务器的地址",8888);
     //构建网络输入输入流
     //网络输入流
     DataInputStream dis=new DataInputStream(new BufferedInputStream(socket.getInputStream()));
     //网络输出流
     DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
     System.out.println("请输出服务端中的文件的路径:");
     String filePath=input.next();
     //把文件路径发送到网络流上
     dos.writeUTF(filePath);
     dos.flush();
     //接收文件名称
     String fileName=dis.readUTF();
     //接收文件的长度
     String length=dis.readUTF();
     //输出
     System.out.println("文件在服务端存在  文件名:"+fileName+"  文件长度="+length);
     //从网络流上接受网络文件数据,并存储到内存,并将内存的数据存储到客户端硬盘
     System.out.println("开始下载...");
     //构建本地流输出
     DataOutputStream dos_local=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/download1/"+fileName)));
     //构建一个缓冲
     byte[] buffer=new byte[1024*4];//要求服务端和客户端缓冲大小要一样
     //循环从网络流中毒入数据进入内存
     while(true){
    	int  len=-1;
    	   if(dis!=null){
    		   //从网络上读数据
    		   len=dis.read(buffer);
    	   }
    	 if(len==-1){
    		 break;
    	 }
    	 dos_local.write(buffer, 0, len);
     }
     dis.close();
     dos.close();
     socket.close();
     dos_local.close();
     System.out.println("接收文件完毕,文件路径d:/download1/"+fileName+",文件大小"+length);
	}
}

上传文件到服务器

/**

  • 从客户端接收文件
  • 1.客户端发送文件的名字和长度在网络流上
  • 2.服务端接收网络流上文件的名字和长度
  • 3.客户端开始发送文件,服务端接收文件
  • @author PC

*/
public class Server {

public static void main(String[] args)throws Exception {
 ServerSocket ss=new ServerSocket(8888);
 while(true){
	 Socket socket=ss.accept();
	 ThreadHandler th=new ThreadHandler(socket);
	 Thread t=new Thread(th);
	 t.start();
			 
 }
}

}
/**

  • 业务逻辑
  • 从客户端接收文件
  • 1.从网络流上接收客户端发送文件的名字和长度到内存
  • 2.客户端开始发送文件,服务端接收文件到本地
  • @author PC

*/

public class ThreadHandler implements Runnable {
private Socket socket;

public ThreadHandler(Socket socket) {

this.socket = socket;

}

@Override
public void run() {
	try {
		//构建网络输入流
		DataInputStream dis=new DataInputStream(new BufferedInputStream(socket.getInputStream()));
	    //接收文件名字和长度
		String fileName=dis.readUTF();
		String length=dis.readUTF();
	    //准备接收文件
		System.out.println("准备接收文件"+fileName+"且文件长度为:"+length);
		DataOutputStream dos_local=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("d:/aa/"+fileName)));
		byte[] buf=new byte[1024*4];
		while(true){
			int len=-1;
			if(dos_local!=null){
				len=dis.read(buf);
			}
			if(len==-1){
				break;
			}
			//写入本地
			dos_local.write(buf, 0, len);
			
		}
		dos_local.flush();
		dos_local.close();
		dis.close();
		socket.close();
 System.out.println("接收完毕");
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

}
/**

  • 从客户端接收文件
  • 1.客户端输入要上传的文件路径
  • 2.客户端发送文件的名字和长度在网络流上
  • 3.客户端开始发送文件,服务端接收文件
  • @author PC

*/
public class Client {

public static void main(String[] args)throws Exception {
	Scanner input=new Scanner(System.in);
	Socket socket=new Socket("10.8.38.101",8888);
	DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
	System.out.println("请输入你要上传的文件的路径");
	String filePath=input.next();//输入文件的路径
    File file=new File(filePath);
    if(!file.exists()){
    	System.out.println("你上传的文件不存在");	
    	return;
    }
	String fileName=file.getName();
	dos.writeUTF(fileName);
	dos.flush();
	long length=file.length();
	dos.writeUTF(length+"");
	dos.flush();
	//开始上传文件
	DataInputStream dis_local=new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
     byte[] buf=new byte[1024*4];
     while(true){
    	 int len=-1;
    	 if (dis_local!=null) {
			len=dis_local.read(buf);
		}
    	 if(len==-1){
    		 break;
    	 }
    	 dos.write(buf, 0, len);
     }
     dos.flush();
     dos.close();
     dis_local.close();
     socket.close();
     System.out.println("发送完毕");
}

}

总结:利用io流,socket套接字,多线程并发,无非就是传送文件或者字符串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值