应用案例:客户端上传一张图片到服务端
- 编写一个服务端,和一个客户端
- 服务器端在 8888 端口监听
- 客户端连接到服务端,发送一张图片:e:\baidu.png
- 服务器端接收到客户端发送的图片,保存到 src 下,发送 “收到图片” 再退出
- 客户端接收到服务端发送的 “收到图片”,再退出
分析:
设计一个 StreamUtils 工具类
package net;
import java.io.*;
/**
* @Author: Gin
* @Description:
* @Modified By: Gin
* @Date: Created in 19:19 2021/10/9
*/
public class StreamUtils {
/**
* 功能:将输入流转换成 byte[],即:可以把文件的内容读入到一个 byte[]
* @param is 输入流对象
* @return 文件内容的 byte[] 数组
* @throws IOException
*/
public static byte[] streamToByteArray(InputStream is) throws IOException {
// 1. 创建字节数组输出流对象 bos
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len;
// 2. 通过 is 循环读取文件,将读取到的数据写入 bos 中
while((len = is.read(b)) != -1){
bos.write(b, 0, len);
}
// 3. 将 bos 转成字节数组,返回给 array
byte[] array = bos.toByteArray();
bos.close();
// 4. array 即为读取的文件的 字节数组
return array;
}
/**
* 功能:将输入流读取到的内容转换成字符串
* @param is
* @return
* @throws IOException
*/
public static String streamToString(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder stringBuilder = new StringBuilder();
String line;
while((line = reader.readLine()) != null){
stringBuilder.append(line + "\r\n");
}
return stringBuilder.toString();
}
}
服务端
package net;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @Author: Gin
* @Description:
* @Modified By: Gin
* @Date: Created in 18:20 2021/10/9
*/
public class TCPFileUploadServer {
public static void main(String[] args) throws IOException {
// 1. 监听 8888 端口,等待连接
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端监听 8888 端口,等待连接......");
// 2. 等待连接
Socket socket = serverSocket.accept();
// 3. 读取客户端发送的数据
// 通过 Socket 得到输入流
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bis);
// 4. 将得到的 bytes 数组写入到指定的路径,就得到一个文件了
String destFilePath = "src\\baidu2.png";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
bos.write(bytes);
// 向客户端回复 ”收到图片“
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("收到图片");
writer.flush(); // 把内容刷新到数据通道
socket.shutdownOutput(); // 设置写入结束标记
// 5. 关闭资源
bos.close();
bis.close();
socket.close();
serverSocket.close();
}
}
客户端
package net;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
* @Author: Gin
* @Description:
* @Modified By: Gin
* @Date: Created in 18:20 2021/10/9
*/
public class TCPFileUploadClient {
public static void main(String[] args) throws IOException {
// 1. 客户端连接服务端 8888 ,并返回 Socket 对象
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
// 2. 创建读取磁盘文件的输入流
String filePath = "E:\\baidu.png";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
// 3. bytes 就是 filePath 对应的字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);
// 4. 通过 socket 获取输出流,将 bytes 写入到数据通道
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes);
// 5. 设置写入数据的结束标记
socket.shutdownOutput();
// 接收从服务端回复的消息
InputStream inputStream = socket.getInputStream();
// 使用 StreamUtils 的方法,直接将 inputStream 读取到的数据转成字符串
String s = StreamUtils.streamToString(inputStream);
System.out.println(s);
// 6. 关闭相关的流
bis.close();
bos.close();
socket.close();
}
}