//1:创建一个服务器端类Server
package cn.abc.demo03;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) throws IOException {
//1:创建服务器端套接字对象server
ServerSocket server = new ServerSocket(8082);
Scanner sc = new Scanner(System.in);//创建扫描器对象sc
while(true){
//2:获取客户端套接字对象socket
System.out.println("服务器监听等待");
Socket socket = server.accept();//监听等待
new Thread(new Runnable() {
@Override
public void run() {
transmitFile(socket,sc);
}
}).start();
}
}
private static void transmitFile(Socket socket,Scanner sc){
try{
//3:创建本地文件字节输出流对象bos
System.out.println("请输入保存文件的绝对路径:");
String filePath = sc.next();
File file = new File(filePath);
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//4:获取客户端网络字节输入流对象is
InputStream is = socket.getInputStream();
//5:is读取客户端输出的文件信息并通过fos保存至硬盘
int len = 0;
byte[] bts = new byte[1024];
while((len = is.read(bts)) != -1){//mark标记
bos.write(bts,0,len);
bos.flush();
}
//6:获取客户端网络字节输出流对象os并发送传输文件接收成功确认信息
OutputStream os = socket.getOutputStream();
os.write("文件接收成功".getBytes());
//7:释放资源
bos.close();
fos.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
//2:创建客户端类
package cn.abc.demo03;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
//1:创建客户端套接字对象client
Socket client = new Socket("127.0.0.1",8082);
//2:创建本地文件字节输入流对象bis
Scanner sc = new Scanner(System.in);//创建扫描器对象sc
System.out.println("请输入上传文件的绝对路径:");
String filePath = sc.next();
File file = new File(filePath);
if(!file.exists()){
System.out.println("本地文件不存在");
System.exit(1);
}
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);//效率高
//3:创建网络字节输出流对象os
OutputStream os = client.getOutputStream();
//4:bis读取本地文件数据并通过os上传到指定服务器
int len = 0;
byte[] bts = new byte[1024];
while((len = bis.read(bts)) != -1){//文件结束标记不会传输至服务器在mark标记处可能会导致IO流阻塞
os.write(bts,0,len);
os.flush();
}
client.shutdownOutput();//防止IO流阻塞[禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,
// 并且后跟 TCP 的正常连接终止序列。 如果在套接字上调用 shutdownOutput() 后写入套接字输出流,则该流将抛出 IOException。 ]
//5:创建网络字节输入流对象is,接收来自服务器的文件接收确认信息
InputStream is = client.getInputStream();
len = is.read(bts);
System.out.println(new String(bts,0,len));
//6:释放资源
bis.close();
fis.close();
client.close();
}
}
//注意:
//4:bis读取本地文件数据并通过os上传到指定服务器
int len = 0;
byte[] bts = new byte[1024];
while((len = bis.read(bts)) != -1){//文件结束标记不会传输至服务器在mark标记处可能会导致IO流阻塞
os.write(bts,0,len);
os.flush();
}
client.shutdownOutput();//防止IO流阻塞[禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,
// 并且后跟 TCP 的正常连接终止序列。 如果在套接字上调用 shutdownOutput() 后写入套接字输出流,则该流将抛出 IOException。 ]