服务端
FileUpLoadSocketServer.java
import cn.hutool.jwt.JWTUtil;
import server.constant.ServerConstant;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FileUpLoadSocketServer {
private final Logger logger = LoggerFactory.getLogger(FileUpLoadSocketServer.class);
private final int POOL_SIZE = 4;
//服务套接字等待对方的连接和文件发送
private ServerSocket serverSocket;
private String token;
private String uploadPath;
private int report;
/**
* description 线程池
*/
private ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);
public FileUpLoadSocketServer(int report, String uploadPath, String token) throws IOException {
this.uploadPath = uploadPath;
this.report = report;
this.token = token;
}
/**
* 使用线程处理每个客户端传输的文件
*
* @throws Exception
*/
public void load() throws Exception {
serverSocket = new ServerSocket(report);
Socket socket = null;
while (true) {
try {
socket = serverSocket.accept();
executorService.execute(new Task(socket));
} catch (Exception e) {
logger.error("服务开启失败!", e);
}
}
}
/**
* 处理客户端传输过来的文件线程类
*/
class Task implements Runnable {
//当前连接
private Socket socket;
public Task(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
logger.info("新连接 " + socket.getInetAddress() + ":" + socket.getPort());
DataInputStream dis = null;
DataOutputStream dos = null;
int bufferSize = 8192;
String fileName = null;
byte[] buf = new byte[bufferSize];
try {
dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
String clientToken = dis.readUTF();
//logger.info("clientToken",clientToken);
if (!JWTUtil.verify(clientToken, token.getBytes())) {
dis.close();
throw new RuntimeException("token验证失败,断开连接!");
}
fileName = dis.readUTF();
//logger.info("fileName",fileName);
String saveFilePath = dis.readUTF();
//logger.info("saveFilePath",saveFilePath);
long fileLength = dis.readLong();
if (StringUtils.isEmpty(saveFilePath)) {
saveFilePath = uploadPath;
}
//不存在文件夹就创建文件夹
File file = new File(saveFilePath);
if(!file.exists()){
file.mkdirs();
}
String savePath = saveFilePath + File.separatorChar + fileName;
//File file = new File(saveFilePath);
//if (file.exists()) {
// dis.close();
// throw new RuntimeException("文件已存在,断开连接!");
//}
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(savePath)));
logger.info("文件: " + FormatUtil.formatSize(fileLength) + " " + saveFilePath);
int read = 0;
long passedlen = 0;
long i = 0;
fileStateCahe.put(fileName, ServerConstant.FILE_STATE.FILE_UPLOAD_UPLOADING);
while ((read = dis.read(buf)) != -1) {
passedlen += read;
dos.write(buf, 0, read);
//if (i < (passedlen * 100L / fileLength)) {
// i = passedlen * 100L / fileLength;
// logger.info("文件已经接收: " + i + "%");
//}
}
logger.info("文件[" + savePath + "]接收完成!");
fileStateCahe.put(fileName, ServerConstant.FILE_STATE.FILE_UPLOAD_COMPLETED);
} catch (RuntimeException e) {
fileStateCahe.put(fileName, ServerConstant.FILE_STATE.FILE_UPLOAD_FAILED);
logger.error("接收失败!", e);
} catch (Exception e) {
fileStateCahe.put(fileName, ServerConstant.FILE_STATE.FILE_UPLOAD_FAILED);
logger.error("接收失败!", e);
} finally {
try {
if (dos != null) {
dos.close();
}
if (dis != null) {
dis.close();
}
if (socket != null) {
socket.close();
}
} catch (Exception e) {
logger.error("", e);
}
}
}
}
}
ServerConstant.java
import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import org.apache.commons.lang3.ObjectUtils;
public interface ServerConstant {
/**
* 上传完成
*/
public static final int FILE_UPLOAD_COMPLETED = 21001;
/**
* 上传中
*/
public static final int FILE_UPLOAD_UPLOADING = 21002;
/**
* 上传失败
*/
public static final int FILE_UPLOAD_FAILED = 21003;
/**
* 文件未查询到
*/
public static final int FILE_NOT_FIND = 21004;
/**
* description 保存文件上传状态
*/
public static Cache<String, FILE_STATE> fileStateCahe = CacheUtil.newFIFOCache(100);
/**
* 文件状态enum
*/
public static enum FILE_STATE {
/**
* 文件上传完成
*/
FILE_UPLOAD_COMPLETED,
/**
* 文件上传中
*/
FILE_UPLOAD_UPLOADING,
/**
* 文件上传失败
*/
FILE_UPLOAD_FAILED,
/**
* 文件未找到
*/
FILE_NOT_FIND,
/**
* 文件已存在
*/
FILE_EXSIT,
/**
* 文件准备开始传输
*/
FILE_UPLOAD_START
}
}
SocketServerListener.java
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.util.Timer;
import java.util.TimerTask;
/**
* @ClassName SocketServerListener
* @date 2022/06/15 09:43:52
*/
public class SocketServerListener
private static final Logger logger = LoggerFactory.getLogger(SocketServerListener.class);
private int socketServerPort;
private String socketStatus;
private String uploadPath;
private String token;
public SocketServerListener(int socketServerPort, String socketStatus, String uploadPath,String token) {
this.socketServerPort = socketServerPort;
this.socketStatus = socketStatus;
this.uploadPath = uploadPath;
this.token = token;
}
// 初始化启动Socket服务
@Async
public void init() throws Exception {
if (ServerConstant.OPEN.equals(socketStatus)) {
open();
}
}
public void open() throws Exception {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@SuppressWarnings("resource")
@Override
public void run() {
try {
FileUpLoadSocketServer fileUpLoadSocketServer = new FileUpLoadSocketServer(socketServerPort, uploadPath,token);
fileUpLoadSocketServer.load();
logger.info("FileUpLoadSocketServer 启动成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}, 3000);
}
}
startSocketServer.java
@Component
public class startSocketServer {
private final Logger logger = LoggerFactory.getLogger(StartSocketServer.class);
@Autowired
private ServerConfig serverConfig;
@Bean
public void startServerListener() {
try {
SocketServerListener socketServerListener = new SocketServerListener();
socketServerListener.init();
System.out.println("启动成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
ServerConfig.java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
//读取yml配置
@Configuration
@ConfigurationProperties(prefix = "base.server")
public class ServerConfig {
private String communicationToken ;
private String defaultUploadPath;
private int socketServerPort;
private String socketStatus;
public String getCommunicationToken() {
return communicationToken;
}
public void setCommunicationToken(String communicationToken) {
this.communicationToken = communicationToken;
}
public String getDefaultUploadPath() {
return defaultUploadPath;
}
public void setDefaultUploadPath(String defaultUploadPath) {
this.defaultUploadPath = defaultUploadPath;
}
public int getSocketServerPort() {
return socketServerPort;
}
public void setSocketServerPort(int socketServerPort) {
this.socketServerPort = socketServerPort;
}
public String getSocketStatus() {
return socketStatus;
}
public void setSocketStatus(String socketStatus) {
this.socketStatus = socketStatus;
}
}
yml
#自定义配置参数
base:
server:
#通信token,server client保持一致
communicationToken: communicationToken
#默认备份位置
defaultUploadPath: E:\Code\xyhz\wwwBackup
#socket文件传输服务端端口号
socketServerPort: 10086
#socket文件传输服务端状态
socketStatus: open
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M2</version>
</dependency>
客户端
SocketFileUpLoadClient.java
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @date 2022/06/15 09:41:50
*/
@Slf4j
public class SocketFileUpLoadClient {
public SocketFileUpLoadClient(String token, String filePath, String ip, Integer report, String saveFilePath) {
ExecutorService taskScheduler = Executors.newCachedThreadPool();
taskScheduler.execute(sendFile(token, filePath, ip, report, saveFilePath));
}
private static Runnable sendFile(String token, String filePath, String ip, int port, String saveFilePath) {
return new Runnable() {
private Socket socket = null;
@Override
public void run() {
File file = new File(filePath);
if (file.exists()) {
if (createConnection()) {
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
try {
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(token);
dos.flush();
//log.info("token:" + token);
dos.writeUTF(file.getName());
dos.flush();
//log.info("file.getName():" + file.getName());
dos.writeUTF(saveFilePath);
dos.flush();
//log.info("saveFilePath:" + saveFilePath);
dos.writeLong(file.length());
dos.flush();
int read = 0;
int passedlen = 0;
//获得要发送文件的长度
long length = file.length();
long i = 0;
log.info("开始发送文件:" + filePath);
long start = System.currentTimeMillis();
while ((read = fis.read(buf)) != -1) {
passedlen += read;
//if (i < passedlen * 100L / length) {
// i = (passedlen * 100L / length);
// log.info("已经发送文件: " + i + "%");
//}
dos.write(buf, 0, read);
dos.flush();
}
dos.flush();
fis.close();
dos.close();
socket.close();
log.info(FormatUtil.formatMillisecond(System.currentTimeMillis() - start) + "文件传输完成![" + filePath + "]" + FormatUtil.formatSize(length));
} catch (Exception e) {
log.error("文件传输失败!", e);
}
}
} else {
log.error("文件不存在[" + filePath + "]");
}
}
private boolean createConnection() {
try {
socket = new Socket(ip, port);
log.info("连接服务器成功!" + ip + ":" + port);
return true;
} catch (Exception e) {
log.error("连接服务器失败!", e);
return false;
}
}
};
}
}
客户端启动
public static void main(String[] args) {
DateTime now = DateTime.now();
DateTime newTime = now.offsetNew(DateField.MINUTE, 10);
Map<String, Object> map = new HashMap<String, Object>();
//签发时间
map.put(JWTPayload.ISSUED_AT, now);
//过期时间
map.put(JWTPayload.EXPIRES_AT, newTime);
//生效时间
map.put(JWTPayload.NOT_BEFORE, now);
map.put("uid", Integer.parseInt("123"));
map.put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 3);
SocketFileUpLoadClient fileUpLoadSocketClient =
new SocketFileUpLoadClient(
JWTUtil.createToken(map,"communicationToken".getBytes()),
"F:\\OS\\cn_windows_server_2019_essentials_x64_dvd_5b386b0b.iso",
"127.0.0.1", 10010,"F:\\");
}