这是一个简单的思路,代码给出具体思路
客户端上传下载具体实现
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
/**
* 客户端
* 1连接服务端下载
* 2从键盘输入服务端计算机中的文件路径,并请求下载
* 3.如果服务端有文件就返回给客户端文件的名称和文件长度
* 4.从网络上获取服务端下载的文件数据进入客户端的内存
* 5,把内存的数据写到客户端的硬盘上
* 1连接服务端上传
* 2.从键盘输入正确的文件路径,文件存在
* 3.获取文件名称和长度,并发给客户端
* 3.从本地获取文件数据写入内存
* 4.从内存写入到服务端
* @author PC
*
*/
public class FileClient {
public static void main(String[] args) throws IOException, Exception {
Scanner input = new Scanner(System.in);
//创建Socket对象(ip地址,端口号)
Socket socket = new Socket("localhost",9992);
//创建网络输入流
DataInputStream dis = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
//创建网络输出流
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
FileClient client = new FileClient();
System.out.println("请选择您需要的功能:1.上传 2.下载");
int choise = input.nextInt();
if(choise==1){
dos.writeUTF("upload");
client.upLoad(dis, dos, socket);//上传
}else{
dos.writeUTF("download");
client.downLoad(dis, dos);
}
//关流
dos.close();
dis.close();
//关闭套接字
socket.close();
}
//下载
public void downLoad(DataInputStream dis,DataOutputStream dos) throws Exception{
Scanner input = new Scanner(System.in);
//提示信息.请输入服务器中需要下载的文件路径
System.out.println("请输入服务器中要下载的文件路径:");
String filePath = input.next();
//创建 文件对象
File file = new File(filePath);
//网络输出流传送文件路径给服务器
dos.writeUTF(filePath);
//清除缓存,这时才是真正写出去了
dos.flush();
//读取服务器传送过来的文件的名称
String fileName = dis.readUTF();
//读取服务器传送过来的文件的长度
String length = dis.readUTF();
//提示信息:文件存在
System.out.println("文件存在: fileName="+fileName+" length="+ length);
System.out.println("文件将保存在d:/aa/bb/文件夹中.开始接收文件...");
//构建本地输出流来写到硬盘,写到到d:/aa/bb/文件夹
DataOutputStream local_dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("d:/aa/bb/"+fileName)));
//缓冲数组,减少和硬盘的交互次数
byte[] buffer = new byte[1024*1024];
//循环写到硬盘
while(true){
//用来接收网络输入流写到数组数据的长度
int len = -1;
if(dis!= null ){
//网络输入流写到数组数据的长度
len = dis.read(buffer);
}
//判断是否读到末尾
if(len == -1){
break;
}
//写入到本地,写一次清除缓存一次
local_dos.write(buffer, 0, len);
local_dos.flush();
}
//关流
local_dos.close();
//提示信息:接收完毕
System.out.println("文件下载完毕 !请在d:/aa/bb/文件夹中查看");
}
//上传
public void upLoad(DataInputStream dis,DataOutputStream dos,Socket socket) throws Exception{
Scanner input = new Scanner(System.in);
//提示用户输入需要上传的文件的路径
System.out.println("请输入客户端需要上传的文件的路径:");
String filePath = input.next();
//构架文件对象
File file = new File(filePath);
//判断该路径下是否有对应文件
for(int i=0;i<3;i++){
//文件不存在
if(!file.exists()){
System.out.println("文件不存在,请确认文件路径是否正确,请重新输入:");
if(i==3){
dis.close();
dos.close();
socket.close();
return;
}
}else break;
}
//有对应文件, 获取文件名称
String fileName = file.getName();
//发送文件名称给服务器端
dos.writeUTF(fileName);
dos.flush();
//获取文件长度
long length = file.length();
//发送文件长度给服务器端
dos.writeUTF(length+"");
dos.flush();
System.out.println("文件将保存在服务器的d:/aa/文件夹中.准备开始上传文件...");
//构建本地输入流,写到内存
DataInputStream local_dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(filePath)));
//构建缓冲
byte[] buffer = new byte[1024*1024];
while(true){
int len =-1;
//判断本地文件是否为空
if(local_dis!=null){
//将数组读取的长度赋给len
len = local_dis.read(buffer);
}
if(len == -1){
break;
}
//将网络输出流读到的数据,读一次写出给服务端一次
dos.write(buffer,0,len);
dos.flush();
}
//关流
local_dis.close();
System.out.println("文件上传完毕 !");
}
}
服务端
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* 多线程,可以给多个客户端提供服务
* @author PC
*
*/
public class FileServer {
public static void main(String[] args) throws Exception {
//创建SeverSocket对象
ServerSocket ss = new ServerSocket(9992);
System.out.println("Server is starting");
while(true){
//开始监听9991端口,这里把服务器挂起
Socket socket = ss.accept();
//线程逻辑
ThreadHeadler headler= new ThreadHeadler(socket);//实现Runnable接口
//创建线程
Thread t1 =new Thread(headler);
t1.start();
}
}
}
线程助手
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class ThreadHeadler implements Runnable {
//任务线程需要的属性
private Socket socket;
//构造方法
public ThreadHeadler(Socket socket){
this.socket= socket;
}
@Override
public void run() {
try {
//网络输入流
DataInputStream dis = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
//网络输出流
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
String choise = dis.readUTF();
FileDownloadAndUpload load = new FileDownloadAndUpload();
if("upload".equals(choise)){
load.upload(socket, dos, dis);
}else if("download".equals(choise)){
load.download(socket,dos,dis);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务端上传下载具体实现
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
/**
* 服务端:给客户端提供服务
* 下载:
* 1.接收客户端发送的文件路径,并判断文件是否存在
* 2.如果文件存在,获取文件的名称和长度,并写到网络上
* 3.从服务器硬盘读取文件内容到内存
* 4,把内存的文件数据写到网络上
* 上传:
* 1.接收客户端传来的文件名称,查看是否已经存在,回馈信息
* 2.获取文件长度
* 3.从网络流写入到内存,在从内存写出到硬盘
* @author PC
*
*/
public class FileDownloadAndUpload {
public void upload(Socket socket,DataOutputStream dos,DataInputStream dis){
try {
//获取网络ip地址
InetAddress ip = socket.getInetAddress();
//网络输入输出流在外面
//从客户端获取网络上传递过来的字符串
String fileName = dis.readUTF();
File file = new File("d:/aa/"+fileName);//上传到d:/aa/
//判断文件是否存在
if(file.exists()){
dos.writeUTF("您请求的文件已在服务器中,请换其他文件");
dos.flush();
return;
}
//获取文件的长度
String length = dis.readUTF();
//准备开始接收文件
System.out.println(ip.getHostAddress()+" fileName="+fileName);//" +length="+length
System.out.println(ip.getHostAddress()+" 开始接收文件..");
//从内存写到硬盘中(本地流)
//本地输出流
DataOutputStream local_dos= new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(file)));
byte[] buffer = new byte[1024*1024];
while(true){
int len=-1;
if(dis!=null){
//网络流输入
len = dis.read(buffer);
}
if(len==-1){
break;
}
//将缓存中的数据读出来,写到硬盘上
local_dos.write(buffer, 0, len);
local_dos.flush();//清除缓存,标记数据写出完毕,此时才将数据写到服务器硬盘上
}
//关流
local_dos.close();
dos.close();
dis.close();
//关闭套接字
socket.close();
System.out.println(ip.getHostAddress()+" fileName="+fileName+" 接收完毕!已保存到服务器d:/aa/中");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void download(Socket socket,DataOutputStream dos,DataInputStream dis){
try {
//获取客户端的ip地址
InetAddress ip = socket.getInetAddress();
//网络输入输出流在外面
//读取网络输入流传来的,服务器的文件路径
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("开始发送文件...");
//构建本地输入流
DataInputStream local_dis= new DataInputStream(
new BufferedInputStream(new FileInputStream(filePath)) );
//缓冲数组
byte[] buffer = new byte[1024*1024];
//将文件写入内存
while(true){
int len = -1;
//判断本地内部是否为空
if(local_dis!=null){
//将读取长度赋给len
len = local_dis.read(buffer);
}
if(len == -1){
break;
}
//网络输出流写出给客户端,写完一次清除一次缓存
dos.write(buffer,0,len);
dos.flush();
}
//关流
local_dis.close();
dos.close();
dis.close();
//关闭套接字
socket.close();
//提示信息传送完毕
System.out.println("文件传送完毕");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}