5 changed files with 181 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||
|
## 文件系统 第二版本 |
||||
|
|
||||
@ -0,0 +1,88 @@ |
|||||
|
package transfer |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
|
||||
|
"io" |
||||
|
"net/http" |
||||
|
"os" |
||||
|
"path/filepath" |
||||
|
) |
||||
|
|
||||
|
// 接收文件
|
||||
|
func ReceiveFiles(remoteAddr string) error { |
||||
|
|
||||
|
resp, err := http.Post(fmt.Sprintf("http://%s/", remoteAddr), "", nil) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
defer resp.Body.Close() |
||||
|
|
||||
|
if resp.StatusCode != http.StatusOK { |
||||
|
return fmt.Errorf("failed to get file info: %s", resp.Status) |
||||
|
} |
||||
|
|
||||
|
var pathInfo struct { |
||||
|
Type string `json:"type"` |
||||
|
Paths []string `json:"paths"` |
||||
|
} |
||||
|
|
||||
|
if err := json.NewDecoder(resp.Body).Decode(&pathInfo); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
if pathInfo.Type == "dir" { |
||||
|
fmt.Printf("Found directory with %d paths:\n", len(pathInfo.Paths)) |
||||
|
for _, path := range pathInfo.Paths { |
||||
|
fmt.Printf("- %s\n", path) |
||||
|
} |
||||
|
fmt.Print("Do you want to download the entire directory? [y/n] ") |
||||
|
var confirm string |
||||
|
if _, err := fmt.Scanln(&confirm); err != nil || (confirm != "y" && confirm != "Y") { |
||||
|
return nil |
||||
|
} |
||||
|
for _, path := range pathInfo.Paths { |
||||
|
if err := downloadFile(remoteAddr, path); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
if len(pathInfo.Paths) != 1 { |
||||
|
return fmt.Errorf("unexpected number of paths: %d", len(pathInfo.Paths)) |
||||
|
} |
||||
|
if err := downloadFile(remoteAddr, pathInfo.Paths[0]); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// 下载文件
|
||||
|
func downloadFile(remoteAddr, path string) error { |
||||
|
path = filepath.ToSlash(path) |
||||
|
resp, err := http.Get(fmt.Sprintf("http://%s/download/%s", remoteAddr, path)) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
defer resp.Body.Close() |
||||
|
|
||||
|
if resp.StatusCode != http.StatusOK { |
||||
|
return fmt.Errorf("failed to download file: %s", resp.Status) |
||||
|
} |
||||
|
|
||||
|
fmt.Printf("Downloading [%s]...\n", path) |
||||
|
out, err := os.Create(path) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
defer out.Close() |
||||
|
|
||||
|
_, err = io.Copy(out, resp.Body) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
fmt.Printf("[✅] Download [%s] Success.\n", path) |
||||
|
return nil |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
module xtcfs |
||||
|
|
||||
|
go 1.22.1 |
||||
|
|
||||
|
require ( |
||||
|
github.com/arl/statsviz v0.6.0 |
||||
|
github.com/gorilla/websocket v1.5.3 |
||||
|
) |
||||
@ -0,0 +1,10 @@ |
|||||
|
github.com/arl/statsviz v0.6.0 h1:jbW1QJkEYQkufd//4NDYRSNBpwJNrdzPahF7ZmoGdyE= |
||||
|
github.com/arl/statsviz v0.6.0/go.mod h1:0toboo+YGSUXDaS4g1D5TVS4dXs7S7YYT5J/qnW2h8s= |
||||
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= |
||||
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= |
||||
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= |
||||
|
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= |
||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= |
||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
|
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= |
||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= |
||||
@ -0,0 +1,73 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"math/rand" |
||||
|
"net/http" |
||||
|
"strconv" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/arl/statsviz" |
||||
|
"github.com/gorilla/websocket" |
||||
|
) |
||||
|
|
||||
|
var upgrader = websocket.Upgrader{ |
||||
|
CheckOrigin: func(r *http.Request) bool { |
||||
|
return true // 允许跨域请求
|
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
func handleConnections(w http.ResponseWriter, r *http.Request) { |
||||
|
// 将HTTP连接升级为WebSocket连接
|
||||
|
conn, err := upgrader.Upgrade(w, r, nil) |
||||
|
if err != nil { |
||||
|
println("Failed to set up WebSocket:", err) |
||||
|
return |
||||
|
} |
||||
|
defer conn.Close() |
||||
|
|
||||
|
// 这里可以添加代码来处理实时状态更新
|
||||
|
// 例如,可以循环接收客户端发送的消息,并发送给所有连接的客户端
|
||||
|
for { |
||||
|
// 接收客户端消息
|
||||
|
messageType, p, err := conn.ReadMessage() |
||||
|
if err != nil { |
||||
|
println("Error reading message:", err) |
||||
|
return |
||||
|
} |
||||
|
println("Received message:", string(p)) |
||||
|
|
||||
|
// 将接收到的消息发送给所有客户端
|
||||
|
err = conn.WriteMessage(messageType, p) |
||||
|
if err != nil { |
||||
|
println("Error sending message:", err) |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func work() { |
||||
|
// Generate some allocations
|
||||
|
m := map[string][]byte{} |
||||
|
|
||||
|
for { |
||||
|
b := make([]byte, 512+rand.Intn(16*1024)) |
||||
|
m[strconv.Itoa(len(m)%(10*100))] = b |
||||
|
|
||||
|
if len(m)%(10*100) == 0 { |
||||
|
m = make(map[string][]byte) |
||||
|
} |
||||
|
|
||||
|
time.Sleep(10 * time.Millisecond) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func main() { |
||||
|
statsviz.RegisterDefault() |
||||
|
go work() |
||||
|
// http.ListenAndServe(":8080", nil)
|
||||
|
http.HandleFunc("/ws", handleConnections) |
||||
|
err := http.ListenAndServe(":8080", nil) |
||||
|
if err != nil { |
||||
|
println("ListenAndServe:", err) |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue