文章目录

背景

在​​《Java网络编程的基础知识》​​文章中,我们学习到了基本的TCP通信程序,也对JAVA网络编程中的Socket类进行了编程练习,本章将通过以上知识,完成客户端文件上传至服务器的实战。

需求说明与分析

  1. 客户端使用字节输入流,读取文件
  2. 客户端使用网络字节输出流,经过TCP通信,向服务端发送数据
  3. 服务端监听得到数据,使用网络字节输入流,读入数据
  4. 服务端通过字节输出流,将读取到的数据,保存到服务器硬盘
  5. 若保存成功,则服务器使用网络字节输出流,向客户端返回"成功",否则返回"失改"
  6. 客户端使用网络字节输入流,读取服务端返回的结果
  7. 释放资源

Java网络编程的实战:通过TCP通信进行文件上传_客户端

文件上传的客户端

/**
* 文件上传客户端--上传一个图片文件
*
* @author zhuhuix
* @date 2020-07-05
*/
public class TCPFileUploadClient {
public static void main(String[] args) throws IOException {
// 通过文件字节输入流读取图片文件
FileInputStream fileInputStream = new FileInputStream("c:\\csdn-logo.png");
// 创建一个客户端Socket对象,并通过getOutputStream方法创建网络字节输出流
Socket socket = new Socket("127.0.0.1", 8090);
OutputStream outputStream = socket.getOutputStream();
// 读取文件数据
int len;
byte[] bytes = new byte[1024];
while ((len = fileInputStream.read(bytes)) != -1) {
// 通过网络字节输出流向服务端发送数据
outputStream.write(bytes, 0, len);
}

// 发送完毕后,关闭输出流,并等待服务端返回结果
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
while ((len = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len));
}
// 释放资源
fileInputStream.close();
socket.close();
}

}

文件上传的服务端

/**
* 文件上传服务端
*
* @author zhuhuix
* @date 2020-07-05
*/
public class TCPFileUploadServer {
public static void main(String[] args) throws IOException {
// 创建ServerSocket对象
ServerSocket serverSocket = new ServerSocket(8090);
Socket socket = null;
boolean finished = false;
while (!finished) {
// 监听端口
socket = serverSocket.accept();
// 定义文件输出字节流
new Thread(new ServerThread(socket)).start();
}
serverSocket.close();

}
}

// 多线程处理客户端请求
class ServerThread implements Runnable {
private Socket socket;

ServerThread(Socket client) {
this.socket = client;
}

@Override
public void run() {
FileOutputStream fileOutputStream = null;
try {
// 创建网络字节输入流
InputStream inputStream = socket.getInputStream();
// 设置文件保存的位置
File file = new File("d:\\upload");
if (!file.exists()) {
file.mkdir();
}
//定义保存文件的名称
String fileName = "file_" + System.nanoTime() + ".png";
fileOutputStream = new FileOutputStream(file + "\\" + fileName);
// 读取网络传输的数据
int len;
byte[] bytes = new byte[1024];
while ((len = inputStream.read(bytes)) != -1) {
// 读取到数据后通过文件输出流保存文件
fileOutputStream.write(bytes, 0, len);
}
socket.getOutputStream().write("上传成功".getBytes());
System.out.println(fileName+"已保存!!");
} catch (IOException ex) {
ex.printStackTrace();
try {
socket.getOutputStream().write("上传失败".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
} finally {
try {
fileOutputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

测试

  1. 首选运行服务端程序,开始监听上传服务端口
  2. 再运行客户端程序,将图片文件上传
  3. Java网络编程的实战:通过TCP通信进行文件上传_客户端_02


  4. Java网络编程的实战:通过TCP通信进行文件上传_客户端_03


  5. Java网络编程的实战:通过TCP通信进行文件上传_客户端_04

  6. 客户端与服务端程序都能正常运行,达到预期。

注意点

  1. 服务端应使用多线程并行处理接收数据与保存文件的过程;
  2. 客户端在读取所有文件数据,并向服务端传输数据后,应关闭socket输出.
  3. Java网络编程的实战:通过TCP通信进行文件上传_客户端_05