|
|
|
@ -1,11 +1,13 @@ |
|
|
|
package main |
|
|
|
|
|
|
|
import ( |
|
|
|
"bufio" |
|
|
|
"flag" |
|
|
|
"fmt" |
|
|
|
"net/rpc" |
|
|
|
"net/rpc/jsonrpc" |
|
|
|
"os" |
|
|
|
"path/filepath" |
|
|
|
|
|
|
|
"scalib/util" |
|
|
|
"strings" |
|
|
|
@ -19,6 +21,14 @@ type FileInfo struct { |
|
|
|
FileSize int64 |
|
|
|
} |
|
|
|
|
|
|
|
// 文件块
|
|
|
|
type FileChunk struct { |
|
|
|
Data []byte |
|
|
|
FileName string |
|
|
|
Offset int64 |
|
|
|
IsLast bool |
|
|
|
} |
|
|
|
|
|
|
|
// 客户端
|
|
|
|
type UpFileClient struct { |
|
|
|
rpcClient *rpc.Client |
|
|
|
@ -70,9 +80,13 @@ func NewUpFileClient(addr string) (*UpFileClient, error) { |
|
|
|
|
|
|
|
// 传输文件
|
|
|
|
func transferFile(c *UpFileClient, curPath string, uploadPath string) error { |
|
|
|
|
|
|
|
// 启用日志
|
|
|
|
logger := util.NewProductionLogger() |
|
|
|
defer logger.Sync() |
|
|
|
// 发送文件信息
|
|
|
|
fmt.Printf("TransferFile filePath: %s, uploadPath: %s\n", curPath, uploadPath) |
|
|
|
// fmt.Printf("TransferFile filePath: %s, uploadPath: %s\n", curPath, uploadPath)
|
|
|
|
// 提取文件名
|
|
|
|
fileName := filepath.Base(curPath) |
|
|
|
// 获取文件信息
|
|
|
|
fileInfo, err := os.Stat(curPath) |
|
|
|
if err != nil { |
|
|
|
@ -82,16 +96,63 @@ func transferFile(c *UpFileClient, curPath string, uploadPath string) error { |
|
|
|
} |
|
|
|
|
|
|
|
// 异步
|
|
|
|
go func() { |
|
|
|
// 发送文件信息
|
|
|
|
var reply string |
|
|
|
c.rpcClient.Call("UpFileService.SendFileInfo", FileInfo{ |
|
|
|
FileName: uploadPath, |
|
|
|
FileSize: fileInfo.Size(), |
|
|
|
// go func() {
|
|
|
|
// 发送文件信息
|
|
|
|
var reply string |
|
|
|
c.rpcClient.Call("UpFileService.SendFileInfo", FileInfo{ |
|
|
|
FileName: uploadPath, |
|
|
|
FileSize: fileInfo.Size(), |
|
|
|
}, &reply) |
|
|
|
// 输出执行的结果
|
|
|
|
if reply != "true" { |
|
|
|
logger.Error("SendFileInfo failed", zap.String("reply", reply)) |
|
|
|
} |
|
|
|
|
|
|
|
// 打开文件准备读取
|
|
|
|
file, err := os.Open(curPath) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
|
defer file.Close() |
|
|
|
|
|
|
|
// 读取并发送文件块
|
|
|
|
buffer := make([]byte, 4096) // 4KB块大小
|
|
|
|
reader := bufio.NewReader(file) |
|
|
|
var offset int64 = 0 |
|
|
|
|
|
|
|
fmt.Printf("开始发送文件: %s (大小: %d bytes)\n", fileName, fileInfo.Size()) |
|
|
|
|
|
|
|
for { |
|
|
|
n, err := reader.Read(buffer) |
|
|
|
if err != nil { |
|
|
|
break |
|
|
|
} |
|
|
|
|
|
|
|
// 判断是否是最后一块
|
|
|
|
isLast := offset+int64(n) >= fileInfo.Size() |
|
|
|
|
|
|
|
// 发送文件块
|
|
|
|
err = c.rpcClient.Call("UpFileService.SendFileChunk", FileChunk{ |
|
|
|
Data: buffer[:n], |
|
|
|
FileName: fileName, |
|
|
|
Offset: offset, |
|
|
|
IsLast: isLast, |
|
|
|
}, &reply) |
|
|
|
// 输出执行的结果
|
|
|
|
fmt.Printf("SendFileInfo result: %v\n", reply) |
|
|
|
}() |
|
|
|
|
|
|
|
if err != nil || reply != "true" { |
|
|
|
panic("发送文件块失败: " + err.Error()) |
|
|
|
} |
|
|
|
|
|
|
|
offset += int64(n) |
|
|
|
|
|
|
|
// 显示进度
|
|
|
|
progress := float64(offset) / float64(fileInfo.Size()) * 100 |
|
|
|
fmt.Printf("\r发送进度: %.2f%%", progress) |
|
|
|
} |
|
|
|
|
|
|
|
fmt.Println("\n文件发送完成!") |
|
|
|
|
|
|
|
// }()
|
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|