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