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

从服务端下载文件

首先我们先做一下服务端

/**
 * 服务端:给客户端提供服务
 * 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套接字,多线程并发,无非就是传送文件或者字符串

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用Java编写的简单示例程序,用于利用和多线程进行网络编程,计算矩形的面积: ```java import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class RectangleServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器已启动..."); while (true) { Socket clientSocket = serverSocket.accept(); System.out.println("客户端连成功..."); Thread thread = new Thread(new RectangleHandler(clientSocket)); thread.start(); } } catch (IOException e) { e.printStackTrace(); } } private static class RectangleHandler implements Runnable { private Socket clientSocket; public RectangleHandler(Socket clientSocket) { this.clientSocket = clientSocket; } @Override public void run() { try { InputStream input = clientSocket.getInputStream(); OutputStream output = clientSocket.getOutputStream(); byte[] lengthBytes = new byte[1024]; int lengthLen = input.read(lengthBytes); String lengthStr = new String(lengthBytes, 0, lengthLen); byte[] widthBytes = new byte[1024]; int widthLen = input.read(widthBytes); String widthStr = new String(widthBytes, 0, widthLen); int length = Integer.parseInt(lengthStr.trim()); int width = Integer.parseInt(widthStr.trim()); int area = length * width; String areaStr = Integer.toString(area); output.write(areaStr.getBytes()); input.close(); output.close(); clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } ``` 在该程序中,我们使用 ServerSocket 类创建了一个服务器套,监听 8888 端口。当客户端连到该端口时,程序将创建一个新的线程来处理客户端请求。在 RectangleHandler 类中,我们收客户端发送的矩形参数,计算矩形面积并将结果发送回客户端。 以下是一个使用Java编写的客户端程序,用于向服务器发送矩形参数,并收服务器返回的面积值: ```java import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class RectangleClient { public static void main(String[] args) { Socket socket = null; InputStream input = null; OutputStream output = null; try { socket = new Socket("localhost", 8888); input = socket.getInputStream(); output = socket.getOutputStream(); int length = 4; int width = 5; String lengthStr = Integer.toString(length); output.write(lengthStr.getBytes()); String widthStr = Integer.toString(width); output.write(widthStr.getBytes()); byte[] areaBytes = new byte[1024]; int areaLen = input.read(areaBytes); String areaStr = new String(areaBytes, 0, areaLen); int area = Integer.parseInt(areaStr.trim()); System.out.println("矩形的面积为:" + area); input.close(); output.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 在该程序中,我们创建了一个套并连到服务器的 8888 端口。我们发送矩形参数(长和宽),并收服务器返回的面积值。最后,我们将计算出的矩形面积打印到控制台上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值