文件的上传下载要保证文件的完整性,所以采用TCP连接
TCP连接是面向连接的、稳定的、安全的传输协议,在OSI的传输层
用户信息类
用户上传文件和下载文件,服务器需要获取用户的信息,这个信息可以封装成用户类
public class HostsMsg {
private String ip;
private int port;
private String hostname;
public HostsMsg(String ip, int port, String hostname) {
this.ip = ip;
this.port = port;
this.hostname = hostname;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
@Override
public String toString() {
return "HostsMsg{" +
"ip='" + ip + '\'' +
", port=" + port +
", hostname='" + hostname + '\'' +
'}';
}
}
文件工具类
文件上传和下载有很多重复的代码,可以封装成一个工具类
public class FileUtils {
//发送文件
public static void sendMsg(Socket socket,String msg) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(msg);
}
//接收文件
public static String receiveMsg(Socket socket) throws IOException {
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
String s = dataInputStream.readUTF();
return s;
}
//发送文件
public static void sendFile(Socket socket, File file) throws IOException {
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream outputStream = socket.getOutputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fileInputStream.read(bytes)) != -1){
outputStream.write(bytes,0,len);
}
}
//接收文件
public static void receiveFile(Socket socket, File file) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(file);
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1){
fileOutputStream.write(bytes,0,len);
}
}
//发送操作类型
public static void sendOperation(Socket socket,OperationType operationType) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(operationType);
}
//接收操作类型
public static OperationType receiveOperation(Socket socket,OperationType operationType) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
OperationType operation = ((OperationType) objectInputStream.readObject());
return operation;
}
}
文件操作枚举类
用户上传下载文件需要操作相关指令,可以用1,2,3进行相应操作,但是要转换,这里采用枚举类,直接将操作类型发送给服务端
public enum OperationType {
UPLOAD,DOWNLOAD,DELETE
}
服务端
public class Server_File {
private ServerSocket serverSocket = null;
private boolean isRun = true;
public Server_File(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
public void start() throws IOException, ClassNotFoundException {
while (isRun) {
System.out.println("服务器启动");
Socket socket = connection();
OperationType operation = receiveOperation(socket);
if (operation == null) continue;
HostsMsg clientMsg = getClientMsg(socket);
File dirOwn = createDirOwn(clientMsg);
if (!dirOwn.exists()) continue;
printHosts(clientMsg, operation);
}
}
public File createDirOwn(HostsMsg hostsMsg){
File file = new File("F:/云盘存储",hostsMsg.getHostname());
if (!file.exists()) {
file.mkdirs();
}
return file;
}
public void action(Socket socket,OperationType operationType,File file) throws IOException {
if (operationType == null) return;
switch (operationType){
case UPLOAD:
upload(socket,file);
break;
case DOWNLOAD:
delete(socket,file);
break;
}
}
private OperationType receiveOperation(Socket socket) throws IOException, ClassNotFoundException {
ObjectInputStream inputStream = (ObjectInputStream) socket.getInputStream();
OperationType operationType = ((OperationType) inputStream.readObject());
return operationType;
}
private void delete(Socket socket,File file) throws IOException {
DataInputStream inputStream = (DataInputStream) socket.getInputStream();
String s = inputStream.readUTF();
}
private void download(Socket socket,File dir) throws IOException {
File[] files = dir.listFiles();
if (files == null || files.length == 0){
FileUtils.sendMsg(socket,"no");
System.out.println("下载失败,没有该文件");
return;
}
//将文件列表发送给客户端
String msg = filesToString(files);
//接收客户端需要下载文件信息
String filename = FileUtils.receiveMsg(socket);
File file = new File(dir,filename);
//判断该文件是否存在
if (file.exists()){
FileUtils.sendMsg(socket,"yes");
}else {
FileUtils.sendMsg(socket,"no");
}
if (file.exists()){
FileUtils.sendFile(socket,file);
System.out.println(filename+"下载成功");
}else {
FileUtils.sendFile(socket,file);
System.out.println("文件不存在");
}
}
private String filesToString(File[] files){
//将多个文件的名字,拼接成一个字符串
StringBuilder stringBuilder = new StringBuilder("");
for (int i = 0; i < files.length; i++) {
stringBuilder.append(i+1).append(".").append(files[i].getName()).append("\r\n");
}
return stringBuilder.toString();
}
private void upload(Socket socket,File dir) throws IOException {
//获得文件名字
String fileName = receiveFileName(socket);
if (fileName == null)return;
//判断该文件是否存在
boolean flag = checkFileExists(dir, fileName);
//发送信息给客户端,告知上传的文件名是否重复
if (flag){
FileUtils.sendMsg(socket,"yes");
}else {
FileUtils.sendMsg(socket,"no");
}
if (flag){
}else {
File file = new File(dir,fileName);
FileUtils.receiveFile(socket,file);
}
}
private boolean checkFileExists(File dir, String fileName) {
File file = new File(dir,fileName);
return file.exists();
}
private String receiveFileName(Socket socket){
String s = null;
try {
s = FileUtils.receiveMsg(socket);
} catch (IOException e) {
System.out.println(socket + "传输上传文件的名字的时候出错");
}
return s;
}
private void printHosts(HostsMsg clientMsg,OperationType operationType) {
System.out.println("用户 == " + clientMsg + " == 已登录,进行了 " + operationType);
}
private HostsMsg getClientMsg(Socket socket) {
String ip = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
String hostName = socket.getInetAddress().getHostName();
return new HostsMsg(ip,port,hostName);
}
public Socket connection() {
try {
Socket accept = serverSocket.accept();
return accept;
} catch (IOException e) {
System.err.println("一个客户端已下线");
}
return null;
}
}
客户端
public class Client_File {
private String ip;
private int port;
public Client_File() {
}
public void start() throws IOException {
Socket socket = connection(ip,port);
}
public Socket connection(String ip,int port) throws IOException {
Socket socket = new Socket(ip,port);
return socket;
}
public void sendMsg(Socket socket,String msg) throws IOException {
FileUtils.sendMsg(socket,msg);
}
public String receiveMsg(Socket socket) throws IOException {
String s = FileUtils.receiveMsg(socket);
return s;
}
public void sendFile(Socket socket, File file) throws IOException {
FileUtils.sendFile(socket,file);
}
public void receiveFile(Socket socket,File file) throws IOException {
FileUtils.receiveFile(socket,file);
}
public void upload(Socket socket,File file) throws IOException, ClassNotFoundException {
sendOperation(socket,OperationType.UPLOAD);
sendMsg(socket,file.getName());
boolean flag = receiveMsg(socket).equals("yes")?true:false;
if (flag){
}else {
sendFile(socket,file);
}
}
private Scanner scanner = new Scanner(System.in);
public void download(Socket socket,File file) throws Exception {
sendOperation(socket,OperationType.DOWNLOAD);
String dir = scanner.next();
String filename = scanner.next();
sendMsg(socket,filename);
boolean flag = receiveMsg(socket).equals("yes") ? true:false;
if (flag){
}else {
receiveFile(socket,new File(dir,filename));
}
}
public void delete(Socket socket,File file) throws IOException {
DataOutputStream outputStream = (DataOutputStream) socket.getOutputStream();
outputStream.writeUTF(file.getName());
}
public void sendOperation(Socket socket,OperationType operationType) throws IOException, ClassNotFoundException {
FileUtils.sendOperation(socket,operationType);
}
public OperationType ReceiveOperation(Socket socket,OperationType operationType) throws IOException, ClassNotFoundException {
OperationType operationType_02 = FileUtils.receiveOperation(socket, operationType);
return operationType_02;
}
}
开启服务端
**public class Server_Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Server_File server_file = new Server_File(9999);
server_file.start();
}
}**
开启客户端
public class Client_Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Client_File client_file = new Client_File();
Socket connection = client_file.connection("127.0.0.1", 9999);
File file = new File("D:/a.txt");
client_file.upload(connection,file);
}
}
效果