案例分析
文件上传案例
1.[客户端]输入流,从硬盘读取文件数据到程序中
2.[客户端]输出流,写出文件数据到服务端
3.[服务端]输入流,读取文件数据到服务端程序
4.[服务端]输出流,写文件数据到服务器硬盘中
![]()
![]()
实现代码
1.TCPClient客户端
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* 客户端
* 读取本地文件,上传到服务器,读取服务器回写的数据
*/
public class TCPClient {
public static void main(String[] args) throws IOException {
// 1.创建一个本地输入流对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("G:\\a.txt");
// 2.创建一个客户端对象Socket,构造方法绑定服务器IP地址和端口号
Socket socket = new Socket("127.0.0.1", 8888);
// 3.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
// 4.使用本地字节输入流读取本地文件
int len=0;
byte[] bytes = new byte[1024];
while ((len=fis.read(bytes)) !=-1){
// 5.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
os.write(bytes,0,len);
}
/*
解决死循环:上传完文件,给服务器写一个结束标记
void shutdownOutput()禁止此套接字的输出流
对于TCP套接字,任何以前写的数据都将被发送,并且后跟TCP的正常连接终止序列,也就是后面加个结束标记
*/
socket.shutdownOutput();
// 6.使用Socket对象中的方法getInputStream()获取网络字节输入流对象InputStream对象
InputStream is = socket.getInputStream();
// 7.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
while ((len=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
// 8.释放资源(Socket)
fis.close();
socket.close();
}
}
2.TCPServerSocket服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/**
* 服务器端:
* 读取客户端上传的文件,保存到服务器硬盘,回写数据
*/
public class TCPServerSocket {
public static void main(String[] args) throws IOException {
//创建服务器对象:绑定端口号
ServerSocket server = new ServerSocket(8888);
/*
让服务器一只处于监听状态:死循环accept方法
有一个客户端上传文件,就下载文件
*/
while (true) {
//获取请求的客户端对象
Socket socket = server.accept();
/*
使用多线程提高服务器效率,
只要有一个客户端上传文件,就开启一个线程
*/
new Thread(new Runnable() {
//完成文件上传任务
@Override
public void run() {
try {
//使用socket对象中的方法getInputStream
InputStream is = socket.getInputStream();
//判断文件夹是否存在,不存在就创建
File file = new File("G:\\load");
if (!file.exists()) {
file.mkdirs();
}
/*
自定义文件的命名规则,防止同名的文件被覆盖
*/
String fileName = "p" + System.currentTimeMillis() + new Random().nextInt(99999) + ".txt";
//创建本地输出流对象
FileOutputStream fos = new FileOutputStream(file + "\\" + fileName);
//边读网络数据边写进文件
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
fos.write(bytes);
}
//使用socket对象中的方法getOutputStream回写数据
OutputStream os = socket.getOutputStream();
os.write("上传成功".getBytes());
//释放资源
fos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
// server.close();//服务器不用关闭
}
}