-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
165 lines (143 loc) · 3.49 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package main
import (
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"github.com/cheggaaa/pb/v3"
"github.com/spf13/cobra"
)
type Action string
const (
ActionList Action = "list"
ActionGet Action = "get"
Scheme = "http://"
)
var (
server, file, action, passwd string
)
func ClientCmd() *cobra.Command {
command := &cobra.Command{
Use: "cli",
Run: func(cmd *cobra.Command, args []string) {
if server == "" {
fmt.Println("err")
return
}
if action != "" {
httpClient(Action(action), file)
} else {
startClient(server, file)
}
},
}
command.Flags().StringVarP(&passwd, "passwd", "", "", "Server password")
command.Flags().StringVarP(&server, "server", "", "", "Server address and port")
command.Flags().StringVarP(&file, "file", "", "", "Upload file name")
command.Flags().StringVarP(&action, "action", "", "", "Client action")
return command
}
// Client: 发送文件
func startClient(serverAddr string, filePath string) {
f, err := os.Open(filePath)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer func() {
_ = f.Close()
}()
// 获取文件信息
fileInfo, err := f.Stat()
if err != nil {
fmt.Println("Error getting file info:", err)
return
}
conn, err := net.Dial("tcp", serverAddr)
if err != nil {
fmt.Println("Error connecting to server:", err)
return
}
defer func() {
_ = conn.Close()
}()
// 发送文件元信息(文件名|文件大小)
meta := fmt.Sprintf("%s|%d\n", fileInfo.Name(), fileInfo.Size())
if _, err = conn.Write([]byte(meta)); err != nil {
fmt.Println("Error sending metadata:", err)
return
}
// 创建进度条
bar := pb.Start64(fileInfo.Size())
bar.Set(pb.Bytes, true)
defer bar.Finish()
// 发送文件数据
proxyWriter := bar.NewProxyWriter(conn)
if _, err = io.Copy(proxyWriter, f); err != nil {
fmt.Println("Error sending file:", err)
return
}
fmt.Println("File sent successfully!")
}
func httpClient(action Action, f string) {
httpServerAddr := fmt.Sprintf("%s%s", Scheme, server)
client := http.Client{}
switch action {
case ActionGet:
url := fmt.Sprintf("%s%s%s?%s=%s", httpServerAddr, PathDownload, f, QueryParamKey, passwd)
resp, err := client.Get(url)
if err != nil {
fmt.Println("Error downloading file:", err)
}
defer func() {
_ = resp.Body.Close()
}()
// 创建文件以保存下载的内容
file, err := os.Create(f)
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer func() {
_ = file.Close()
}()
// 将响应的内容写入文件
if _, err = io.Copy(file, resp.Body); err != nil {
fmt.Println("Error writing to file:", err)
return
}
fmt.Println("File downloaded successfully!")
case ActionList:
url := fmt.Sprintf("%s%s?%s=%s", httpServerAddr, PathList, QueryParamKey, passwd)
resp, err := client.Get(url)
if err != nil {
fmt.Println("Error downloading file:", err)
}
defer func() {
_ = resp.Body.Close()
}()
// 读取响应的body
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response body:", err)
return
}
// 将body转换为map
var data map[string]interface{}
if err = json.Unmarshal(body, &data); err != nil {
fmt.Println("Error unmarshaling JSON:", err)
return
}
fmt.Println("File List:")
if val, ok := data["data"]; ok && val != nil {
list := val.([]interface{})
for i, item := range list {
fmt.Printf("Num:%d File: %s\n", i+1, item)
}
}
default:
fmt.Println("no support action")
}
}