【案类:上传文件】–优化(文件命名、循环接收处于监听状态、多线程提高效率)
服务端
package Net_02;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/*
* 服务端:读取客户端上传的数据,保存到服务端的硬盘,给客户端回写“上传成功!”
* 实现步骤:
* 1.创建服务端ServerSocket对象,绑定端口号
* 2.使用服务端对象的方法accept();接收客户端
* 3.使用客户端的方法获取网络字节输入流,读取客户端传来的数据
*
* 4.判断 服务端的硬盘中是否有则这个文件夹,没有就创建
* 5.创建字节输出流对象,绑定目的地
*
* 6.服务端使用客户端的网络字节输入流对象的方法read();读取客户端传来的文件
* 7.服务端使用服务端本地的字节输出流对象的方法write();把数据写入到硬盘中
*
* 8.使用客户端的方法获取网络字节输出流
* 9.使用客户端的网络输出流对象的方法write();给客户端回写“上传成功!”
*
* 10.释放资源
* */
public class Test_ServerSocket {
public static void main(String[] args) throws IOException {
//1.
ServerSocket serverSocket = new ServerSocket(8888);
/*
* 【【【让服务器一直处于监听状态(死循环)】】】
* 有一个客户端上传文件,就保存一个文件
* */
while (true) {
//2.
Socket accept = serverSocket.accept();
/*
* 【【【使用多线程技术,提高程序的效率】】】
* 有一个客户端上传文件,就开启一个线程,完成文件的上传
* */
new Thread(new Runnable() {
//完成文件的上传
@Override
public void run() {
try {
//3.
InputStream inputStream = accept.getInputStream();
//4.判断文件是否存在,不存在则创建
File file = new File("D:\\ServerUpload");
if (!file.exists()) {
file.mkdirs();
}
/* 优化(文件命名、循环接受、多线程提高效率)
* 【【【自定义一个文件的命名:防止同名的文件覆盖】】】
* 规则:域名+毫秒值+随机数 +“type”
*
* */
String filename = "服务端下载" + System.currentTimeMillis() + new Random().nextInt(99999) + ".jpg";
//5.创建本地字节输出流对象,构造方法中绑定绑定输出的目的地
// FileOutputStream fos = new FileOutputStream(file + "\\wnx.jpg");
FileOutputStream fos = new FileOutputStream(file + "\\" + filename);
//6.
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
//7.使用本地字节输出流对象的方法write();把数据写到服务器硬盘上的指定文件文件中
fos.write(bytes, 0, len);
}
//8.获取网络字节输出流
OutputStream outputStream = accept.getOutputStream();
//9.
outputStream.write("上传成功!".getBytes());
//10.
fos.close();
accept.close();
} catch (IOException e) {
System.out.println(e);
}
}
}).start();
}
//用了死循环,服务器就用关闭啦!
//serverSocket.close();
}
}
客户端:
package Net_02;
import java.io.*;
import java.net.Socket;
/*【案类:上传文件】
* 客户端:
* 实现步骤:
* 1.创建文件字节输入流读取(绑定数据源)---读取本地硬盘的数据
* 2.创建客户端(绑定IP地址,端口号)
* 3.创建客户端的网络字节输出流
* 4.使用文件字节输入流对象的方法read---读取本地数据
* 5.使用网络字节输出流对象的方法write---把数据写到输出流
* 6.使用网络字节输入流对象的方法read---读取服务器回写的数据
* 7.释放资源
* */
public class Test_Socket {
public static void main(String[] args) throws IOException {
//1.创建文件字节输入流,构造方法绑定数据源
FileInputStream fis = new FileInputStream("F:\\wx.jpg");
//2.创建客户端对象,绑定服务端的IP地址、端口号
Socket socket = new Socket("127.0.0.1", 8888);
//3.使用客户端端Socket对象的方法获取网络字节输出流
OutputStream os = socket.getOutputStream();
byte[] bytes = new byte[1024];
int len = 0;
//4.使用字节输入流读取数据存储到数组中,并记录字节个数
while ((len = fis.read(bytes)) != -1) {
//5.使用网络字节输出流把数据写到网络字节输出流
os.write(bytes, 0, len);
}
/*
*上传完文件,给服务器一个结束标记!
* */
socket.shutdownOutput();
//6.使用客户端端Socket对象的方法获取网络字节输入流
InputStream is = socket.getInputStream();
while ((len = is.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len));
}
//7.释放资源
is.close();
socket.close();
}
}
