這篇文章主要講解了“怎么使用java Netty實(shí)現(xiàn)傳輸文件、分片發(fā)送、斷點(diǎn)續(xù)傳”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么使用java Netty實(shí)現(xiàn)傳輸文件、分片發(fā)送、斷點(diǎn)續(xù)傳”吧!
成都創(chuàng)新互聯(lián)成立與2013年,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元郁南做網(wǎng)站,已為上家服務(wù),為郁南各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792
1、jdk1.8【jdk1.7以下只能部分支持netty】
2、Netty4.1.36.Final【netty3.x 4.x 5每次的變化較大,接口類名也隨著變化】
itstack-demo-netty-2-04
└── src
├── main
│ └── java
│ └── org.itstack.demo.netty
│ ├── client
│ │ ├── MyChannelInitializer.java
│ │ ├── MyClientHandler.java
│ │ └── NettyClient.java
│ ├── codec
│ │ ├── ObjDecoder.java
│ │ └── ObjEncoder.java
│ ├── domain
│ │ ├── Constants.java
│ │ ├── FileBurstData.java
│ │ ├── FileBurstInstruct.java
│ │ ├── FileDescInfo.java
│ │ └── FileTransferProtocol.java
│ ├── server
│ │ ├── MyChannelInitializer.java
│ │ ├── MyServerHandler.java
│ │ └── NettyServer.java
│ └── util
│ ├── CacheUtil.java
│ ├── FileUtil.java
│ ├── MsgUtil.java
│ └── SerializationUtil.java
│
└── test
└── java
└── org.itstack.demo.test
├── ApiTest.java
├── NettyClientTest.java
└── NettyServerTest.java
演示部分重點(diǎn)代碼塊,完整代碼下載關(guān)注公眾號(hào);bugstack蟲洞棧
client/MyClientHandler.java *文件客戶端;channelRead處理文件協(xié)議,其中模擬傳輸過程中斷,場(chǎng)景測(cè)試可以注釋掉
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//數(shù)據(jù)格式驗(yàn)證
if (!(msg instanceof FileTransferProtocol)) return;
FileTransferProtocol fileTransferProtocol = (FileTransferProtocol) msg;
//0傳輸文件'請(qǐng)求'、1文件傳輸'指令'、2文件傳輸'數(shù)據(jù)'
switch (fileTransferProtocol.getTransferType()) {
case 1:
FileBurstInstruct fileBurstInstruct = (FileBurstInstruct) fileTransferProtocol.getTransferObj();
//Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
if (Constants.FileStatus.COMPLETE == fileBurstInstruct.getStatus()) {
ctx.flush();
ctx.close();
System.exit(-1);
return;
}
FileBurstData fileBurstData = FileUtil.readFile(fileBurstInstruct.getClientFileUrl(), fileBurstInstruct.getReadPosition());
ctx.writeAndFlush(MsgUtil.buildTransferData(fileBurstData));
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " bugstack蟲洞??蛻舳藗鬏斘募畔ⅰILE:" + fileBurstData.getFileName() + " SIZE(byte):" + (fileBurstData.getEndPos() - fileBurstData.getBeginPos()));
break;
default:
break;
}
/**模擬傳輸過程中斷,場(chǎng)景測(cè)試可以注釋掉
*
*/
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " bugstack蟲洞??蛻舳藗鬏斘募畔主動(dòng)斷開鏈接,模擬斷點(diǎn)續(xù)傳]");
ctx.flush();
ctx.close();
System.exit(-1);
}
domain/FileBurstData.java *文件分片數(shù)據(jù)塊
/**
* 文件分片數(shù)據(jù)
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:①群5398358 ②群5360692
* Create by fuzhengwei on 2019
*/
public class FileBurstData {
private String fileUrl; //客戶端文件地址
private String fileName; //文件名稱
private Integer beginPos; //開始位置
private Integer endPos; //結(jié)束位置
private byte[] bytes; //文件字節(jié);再實(shí)際應(yīng)用中可以使用非對(duì)稱加密,以保證傳輸信息安全
private Integer status; //Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
... get/set
}
domain/FileBurstInstruct.java *文件分片指令
/**
* 文件分片指令
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:①群5398358 ②群5360692
* Create by fuzhengwei on @2019
*/
public class FileBurstInstruct {
private Integer status; //Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
private String clientFileUrl; //客戶端文件URL
private Integer readPosition; //讀取位置
... get/set
}
domain/FileDescInfo.java *文件傳輸信息
/**
* 文件描述信息
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:①群5398358 ②群5360692
* Create by fuzhengwei on @2019
*/
public class FileDescInfo {
private String fileUrl;
private String fileName;
private Long fileSize;
... get/set
}
domain/FileTransferProtocol.java *文件傳輸協(xié)議
/**
* 文件傳輸協(xié)議
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:5360692
* Create by fuzhengwei on @2019
*/
public class FileTransferProtocol {
private Integer transferType; //0請(qǐng)求傳輸文件、1文件傳輸指令、2文件傳輸數(shù)據(jù)
private Object transferObj; //數(shù)據(jù)對(duì)象;(0)FileDescInfo、(1)FileBurstInstruct、(2)FileBurstData
... get/set
}
serverMyServerHandler.java *文件服務(wù)端;channelRead處理文件協(xié)議,并包含了保存續(xù)傳信息,用于斷點(diǎn)續(xù)傳
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//數(shù)據(jù)格式驗(yàn)證
if (!(msg instanceof FileTransferProtocol)) return;
FileTransferProtocol fileTransferProtocol = (FileTransferProtocol) msg;
//0傳輸文件'請(qǐng)求'、1文件傳輸'指令'、2文件傳輸'數(shù)據(jù)'
switch (fileTransferProtocol.getTransferType()) {
case 0:
FileDescInfo fileDescInfo = (FileDescInfo) fileTransferProtocol.getTransferObj();
//斷點(diǎn)續(xù)傳信息,實(shí)際應(yīng)用中需要將斷點(diǎn)續(xù)傳信息保存到數(shù)據(jù)庫(kù)中
FileBurstInstruct fileBurstInstructOld = CacheUtil.burstDataMap.get(fileDescInfo.getFileName());
if (null != fileBurstInstructOld) {
if (fileBurstInstructOld.getStatus() == Constants.FileStatus.COMPLETE) {
CacheUtil.burstDataMap.remove(fileDescInfo.getFileName());
}
//傳輸完成刪除斷點(diǎn)信息
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " bugstack蟲洞棧服務(wù)端,接收客戶端傳輸文件請(qǐng)求[斷點(diǎn)續(xù)傳]。" + JSON.toJSONString(fileBurstInstructOld));
ctx.writeAndFlush(MsgUtil.buildTransferInstruct(fileBurstInstructOld));
return;
}
//發(fā)送信息
FileTransferProtocol sendFileTransferProtocol = MsgUtil.buildTransferInstruct(Constants.FileStatus.BEGIN, fileDescInfo.getFileUrl(), 0);
ctx.writeAndFlush(sendFileTransferProtocol);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " bugstack蟲洞棧服務(wù)端,接收客戶端傳輸文件請(qǐng)求。" + JSON.toJSONString(fileDescInfo));
break;
case 2:
FileBurstData fileBurstData = (FileBurstData) fileTransferProtocol.getTransferObj();
FileBurstInstruct fileBurstInstruct = FileUtil.writeFile("E://", fileBurstData);
//保存斷點(diǎn)續(xù)傳信息
CacheUtil.burstDataMap.put(fileBurstData.getFileName(), fileBurstInstruct);
ctx.writeAndFlush(MsgUtil.buildTransferInstruct(fileBurstInstruct));
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " bugstack蟲洞棧服務(wù)端,接收客戶端傳輸文件數(shù)據(jù)。" + JSON.toJSONString(fileBurstData));
//傳輸完成刪除斷點(diǎn)信息
if (fileBurstInstruct.getStatus() == Constants.FileStatus.COMPLETE) {
CacheUtil.burstDataMap.remove(fileBurstData.getFileName());
}
break;
default:
break;
}
}
util/FileUtil.java *文件讀寫工具,分片讀取寫入處理類
/**
* 文件讀寫工具
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:5360692
* Create by fuzhengwei on @2019
*/
public class FileUtil {
public static FileBurstData readFile(String fileUrl, Integer readPosition) throws IOException {
File file = new File(fileUrl);
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");//r: 只讀模式 rw:讀寫模式
randomAccessFile.seek(readPosition);
byte[] bytes = new byte[1024];
int readSize = randomAccessFile.read(bytes);
if (readSize <= 0) {
randomAccessFile.close();
return new FileBurstData(Constants.FileStatus.COMPLETE);//Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
}
FileBurstData fileInfo = new FileBurstData();
fileInfo.setFileUrl(fileUrl);
fileInfo.setFileName(file.getName());
fileInfo.setBeginPos(readPosition);
fileInfo.setEndPos(readPosition + readSize);
//不足1024需要拷貝去掉空字節(jié)
if (readSize < 1024) {
byte[] copy = new byte[readSize];
System.arraycopy(bytes, 0, copy, 0, readSize);
fileInfo.setBytes(copy);
fileInfo.setStatus(Constants.FileStatus.END);
} else {
fileInfo.setBytes(bytes);
fileInfo.setStatus(Constants.FileStatus.CENTER);
}
randomAccessFile.close();
return fileInfo;
}
public static FileBurstInstruct writeFile(String baseUrl, FileBurstData fileBurstData) throws IOException {
if (Constants.FileStatus.COMPLETE == fileBurstData.getStatus()) {
return new FileBurstInstruct(Constants.FileStatus.COMPLETE); //Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
}
File file = new File(baseUrl + "/" + fileBurstData.getFileName());
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");//r: 只讀模式 rw:讀寫模式
randomAccessFile.seek(fileBurstData.getBeginPos()); //移動(dòng)文件記錄指針的位置,
randomAccessFile.write(fileBurstData.getBytes()); //調(diào)用了seek(start)方法,是指把文件的記錄指針定位到start字節(jié)的位置。也就是說程序?qū)膕tart字節(jié)開始寫數(shù)據(jù)
randomAccessFile.close();
if (Constants.FileStatus.END == fileBurstData.getStatus()) {
return new FileBurstInstruct(Constants.FileStatus.COMPLETE); //Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
}
//文件分片傳輸指令
FileBurstInstruct fileBurstInstruct = new FileBurstInstruct();
fileBurstInstruct.setStatus(Constants.FileStatus.CENTER); //Constants.FileStatus {0開始、1中間、2結(jié)尾、3完成}
fileBurstInstruct.setClientFileUrl(fileBurstData.getFileUrl()); //客戶端文件URL
fileBurstInstruct.setReadPosition(fileBurstData.getEndPos() + 1); //讀取位置
return fileBurstInstruct;
}
}
util/MsgUtil.java *傳輸消息體構(gòu)建工具類
/**
* 消息構(gòu)建工具
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:5360692
* Create by fuzhengwei on @2019
*/
public class MsgUtil {
/**
* 構(gòu)建對(duì)象;請(qǐng)求傳輸文件(客戶端)
*
* @param fileUrl 客戶端文件地址
* @param fileName 文件名稱
* @param fileSize 文件大小
* @return 傳輸協(xié)議
*/
public static FileTransferProtocol buildRequestTransferFile(String fileUrl, String fileName, Long fileSize) {
FileDescInfo fileDescInfo = new FileDescInfo();
fileDescInfo.setFileUrl(fileUrl);
fileDescInfo.setFileName(fileName);
fileDescInfo.setFileSize(fileSize);
FileTransferProtocol fileTransferProtocol = new FileTransferProtocol();
fileTransferProtocol.setTransferType(0);//0請(qǐng)求傳輸文件、1文件傳輸指令、2文件傳輸數(shù)據(jù)
fileTransferProtocol.setTransferObj(fileDescInfo);
return fileTransferProtocol;
}
/**
* 構(gòu)建對(duì)象;文件傳輸指令(服務(wù)端)
* @param status 0請(qǐng)求傳輸文件、1文件傳輸指令、2文件傳輸數(shù)據(jù)
* @param clientFileUrl 客戶端文件地址
* @param readPosition 讀取位置
* @return 傳輸協(xié)議
*/
public static FileTransferProtocol buildTransferInstruct(Integer status, String clientFileUrl, Integer readPosition) {
FileBurstInstruct fileBurstInstruct = new FileBurstInstruct();
fileBurstInstruct.setStatus(status);
fileBurstInstruct.setClientFileUrl(clientFileUrl);
fileBurstInstruct.setReadPosition(readPosition);
FileTransferProtocol fileTransferProtocol = new FileTransferProtocol();
fileTransferProtocol.setTransferType(Constants.TransferType.INSTRUCT); //0傳輸文件'請(qǐng)求'、1文件傳輸'指令'、2文件傳輸'數(shù)據(jù)'
fileTransferProtocol.setTransferObj(fileBurstInstruct);
return fileTransferProtocol;
}
/**
* 構(gòu)建對(duì)象;文件傳輸指令(服務(wù)端)
*
* @return 傳輸協(xié)議
*/
public static FileTransferProtocol buildTransferInstruct(FileBurstInstruct fileBurstInstruct) {
FileTransferProtocol fileTransferProtocol = new FileTransferProtocol();
fileTransferProtocol.setTransferType(Constants.TransferType.INSTRUCT); //0傳輸文件'請(qǐng)求'、1文件傳輸'指令'、2文件傳輸'數(shù)據(jù)'
fileTransferProtocol.setTransferObj(fileBurstInstruct);
return fileTransferProtocol;
}
/**
* 構(gòu)建對(duì)象;文件傳輸數(shù)據(jù)(客戶端)
*
* @return 傳輸協(xié)議
*/
public static FileTransferProtocol buildTransferData(FileBurstData fileBurstData) {
FileTransferProtocol fileTransferProtocol = new FileTransferProtocol();
fileTransferProtocol.setTransferType(Constants.TransferType.DATA); //0傳輸文件'請(qǐng)求'、1文件傳輸'指令'、2文件傳輸'數(shù)據(jù)'
fileTransferProtocol.setTransferObj(fileBurstData);
return fileTransferProtocol;
}
}
test/NettyServerTest.java *服務(wù)端啟動(dòng)器
/**
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:①群5398358 ②群5360692
* Create by fuzhengwei on 2019
*/
public class NettyServerTest {
public static void main(String[] args) {
//啟動(dòng)服務(wù)
new NettyServer().bing(7397);
}
}
test/NettyClientTest.java *客戶端啟動(dòng)器
/**
* 蟲洞棧:https://bugstack.cn
* 公眾號(hào):bugstack蟲洞棧 {獲取學(xué)習(xí)源碼}
* 蟲洞群:①群5398358 ②群5360692
* Create by fuzhengwei on 2019
*/
public class NettyClientTest {
public static void main(String[] args) {
//啟動(dòng)客戶端
ChannelFuture channelFuture = new NettyClient().connect("127.0.0.1", 7397);
//文件信息{文件大于1024kb方便測(cè)試斷點(diǎn)續(xù)傳}
File file = new File("C:\\Users\\fuzhengwei\\Desktop\\測(cè)試傳輸文件.rar");
FileTransferProtocol fileTransferProtocol = MsgUtil.buildRequestTransferFile(file.getAbsolutePath(), file.getName(), file.length());
//發(fā)送信息;請(qǐng)求傳輸文件
channelFuture.channel().writeAndFlush(fileTransferProtocol);
}
}
啟動(dòng)NettyServerTest *默認(rèn)接收地址為E盤根目錄
啟動(dòng)NettyClientTest *設(shè)置傳輸文件
文件傳輸結(jié)果
服務(wù)端執(zhí)行結(jié)果
itstack-demo-netty server start done. {關(guān)注公眾號(hào):bugstack蟲洞棧,獲取源碼}
鏈接報(bào)告開始
鏈接報(bào)告信息:有一客戶端鏈接到本服務(wù)端。channelId:3a1df8c1
鏈接報(bào)告IP:127.0.0.1
鏈接報(bào)告Port:7397
鏈接報(bào)告完畢
2019-08-04 19:46:46 bugstack蟲洞棧服務(wù)端,接收客戶端傳輸文件請(qǐng)求。{"fileName":"測(cè)試傳輸文件.rar","fileSize":1400,"fileUrl":"C:\\Users\\fuzhengwei1\\Desktop\\測(cè)試傳輸文件.rar"}
2019-08-04 19:46:46 bugstack蟲洞棧服務(wù)端,接收客戶端傳輸文件數(shù)據(jù)。{"beginPos":0,"bytes":"UmFyIRoHAM+QcwAADQAAAAAAAAC4C3SgkkkAFAUAAIjDEQACJRsHe0WECE8dMyQAIAAAALLiytS0q8rkzsS8/i50eHQAbWpL1YsgT5OPoIdl9k4udAB4dACwS2heCZgVEQzPzUEXfAnhs2R75rhNbCQhNE3uMY4EBkBqQJ45izS4lFGujEk08xLGuhp4sSUSbzEscRICakGyOdARhIE6GEPucySJpY5kQ/Cq28ur4XdfH/j1V8UVoo5X5V+B3dl2f8qvvoxd3t6GPv8HZ7dXs+98XT6uJ0Oj8GZ4c6tvV6vzV865ka375utod+9i+pX/O1Uu1tT76tT38TE+Hq+tzud6Of9Xo9T0/S/xytLm12v4NWztfhnda3lbevs7dnXsWL1vT3Kte91triqYuHW/9bf3WPnjq5r5savbHd67V8Nu6r5+lmZtrP0eO63Ba+upVuWtf7bvByg2/0w+5hz8ru14ND5ex/Odw4F7uRWrYedwU2tXmw5m1u+S7lWdjvTq5e/Kv+1apZxrdjT2dHizdHDrlrH1cvkbrWe5k97u6WRnXdviw6zkvc3cD9TOt7+7W9z2/Ys+Sx9VTPwGeYLmrz+h8fQt5u5v8/3fZ5sXKnc4MOT1+n0upicmOVDT86GfY4bPf5vN7XSxMT5Mnsdry8e84///+quHp9l19fRz8vkds+O7qb+9pWe1WvXdb7NWza3vNO3V3cZZ2rPDr1svHwO3Nq14sBuZu3P1zOvuWP++s8ex9O95e5U/vW9/F7Jtb+p+PGeRtzlg8VfG5t5TyAAAAAAAAAAAAAAAARu1PHU9QX3wAAAAAAAAAAAAAAAiiXyXwAAAAAAAAAAAAAAAiiXyXwAAAAAAAAAAAAAAAiiXyXwAAAAAAAAAAAAAAAiiXyXwAEbDTyAAAAAAAAAAAAAEctTx1PUF98AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8AAAABHx08gAAAAAAAAAAj108dT1BffAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAgankAAAAAAAEZGnjqeoL74AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAEYinkAAAAEH08dT1BffAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAA==","endPos":1024,"fileName":"測(cè)試傳輸文件.rar","fileUrl":"C:\\Users\\fuzhengwei1\\Desktop\\測(cè)試傳輸文件.rar","status":1}
2019-08-04 19:46:46 bugstack蟲洞棧服務(wù)端,接收客戶端傳輸文件數(shù)據(jù)。{"beginPos":1025,"bytes":"AAI8VPIAEfZTx1PUF98AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8AAAAAAAAAAAAAAAIol8l8R+dPIAAAAAAAAAAAAAAAjt08dT1BffAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAAAAAAAAAAAAACKJfJfAAAIWp5AAAAAAAAAAAAEYGnjqeoL74AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAAAAAARRL5L4AAAAAAAAAAAAAAARRL5L4AAAAABGYp5AAAAAAAAAEc/Tx1PUF98AAAAAAAAIyFPIAAAAAACB6eOp6gvvgAAAAAAAAAARiKeQAAAAQfTx1PUF98AAAAAAAAAAAAAjAU8gACF6eOp6gvvgAAAAAAAAAAAAAABFH9IDEPXsAQAcA","endPos":1400,"fileName":"測(cè)試傳輸文件.rar","fileUrl":"C:\\Users\\fuzhengwei1\\Desktop\\測(cè)試傳輸文件.rar","status":2}
客戶端斷開鏈接/127.0.0.1:7397
Process finished with exit code -1
客戶端執(zhí)行結(jié)果
itstack-demo-netty client start done. {關(guān)注公眾號(hào):bugstack蟲洞棧,獲取源碼}
鏈接報(bào)告開始
鏈接報(bào)告信息:本客戶端鏈接到服務(wù)端。channelId:71399d8c
鏈接報(bào)告IP:127.0.0.1
鏈接報(bào)告Port:54974
鏈接報(bào)告完畢
2019-08-04 19:46:46 bugstack蟲洞棧客戶端傳輸文件信息。FILE:測(cè)試傳輸文件.rar SIZE(byte):1024
2019-08-04 19:46:46 bugstack蟲洞??蛻舳藗鬏斘募畔ⅰILE:測(cè)試傳輸文件.rar SIZE(byte):375
Process finished with exit code -1
感謝各位的閱讀,以上就是“怎么使用java Netty實(shí)現(xiàn)傳輸文件、分片發(fā)送、斷點(diǎn)續(xù)傳”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)怎么使用java Netty實(shí)現(xiàn)傳輸文件、分片發(fā)送、斷點(diǎn)續(xù)傳這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
網(wǎng)頁(yè)題目:怎么使用javaNetty實(shí)現(xiàn)傳輸文件、分片發(fā)送、斷點(diǎn)續(xù)傳
URL分享:http://muchs.cn/article8/piehop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、面包屑導(dǎo)航、關(guān)鍵詞優(yōu)化、微信小程序、定制網(wǎng)站、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)