-
Notifications
You must be signed in to change notification settings - Fork 0
/
FTPClient.go
123 lines (106 loc) · 2.02 KB
/
FTPClient.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
/*
FTPClient
本程序协议支持三种命令
DIR 返回当前目录下文件和文件夹
CD <dir> 进入子目录
PWD 请求当前工作目录
*/
package main
import (
"bufio"
"bytes"
"fmt"
"net"
"os"
"strings"
)
// string used by the user interface
const (
uiDir = "dir"
uiCd = "cd"
uiPwd = "pwd"
uiQuit = "quit"
)
const (
DIR = "DIR"
CD = "CD"
PWD = "PWD"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: ", os.Args[0], " host:port")
os.Exit(1)
}
host := os.Args[1]
conn, err := net.Dial("tcp", host)
checkError(err)
// 标准输入设备
reader := bufio.NewReader(os.Stdin)
for {
// 读取一行
line, err := reader.ReadString('\n')
line = strings.TrimRight(line, "\t\r\n")
if err != nil {
break
}
// 切分命令和参数
strs := strings.SplitN(line, " ", 2)
switch strs[0] {
case uiDir:
dirRequest(conn)
case uiCd:
if len(strs) != 2 {
fmt.Println("cd <dir>")
continue
}
fmt.Println("CD \"", strs[1], "\"")
cdRequest(conn, strs[1])
case uiPwd:
pwdRequest(conn)
case uiQuit:
conn.Close()
os.Exit(0)
default:
fmt.Println("Unknow command")
}
}
}
func dirRequest(conn net.Conn) {
conn.Write([]byte(DIR + " "))
var buf [512]byte
result := bytes.NewBuffer(nil)
for {
n, _ := conn.Read(buf[0:])
result.Write(buf[0:n])
length := result.Len()
contents := result.Bytes()
if string(contents[length-4:]) == "\r\n\r\n" {
fmt.Println(string(contents[0 : length-4]))
return
}
}
}
func cdRequest(conn net.Conn, dir string) {
conn.Write([]byte(CD + " " + dir))
var response [512]byte
n, _ := conn.Read(response[0:])
s := string(response[0:n])
if s != "OK" {
fmt.Println("Failed to change dir")
} else {
fmt.Println("OK")
}
}
func pwdRequest(conn net.Conn) {
conn.Write([]byte(PWD))
var response [512]byte
n, _ := conn.Read(response[0:])
s := string(response[0:n])
fmt.Println("Current dir \"" + s + "\"")
}
func checkError(err error) {
if err != nil {
fmt.Println("Fatal error ", err.Error())
os.Exit(1)
}
}