-
Notifications
You must be signed in to change notification settings - Fork 6
/
nc.go
134 lines (112 loc) · 2.56 KB
/
nc.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
package main
import (
"bufio"
"flag"
"fmt"
"golang.org/x/text/encoding/simplifiedchinese"
"io"
"log"
"nc/proto"
"net"
"os"
"os/exec"
"runtime"
"strings"
)
/*
10.存在的问题,如果对方文本是utf-8编码的,操作系统是windows,这边识别的是windows就全部按照gbk解码了
这不又乱码了吗 , 鸡肋啊
*/
type Charset string
const (
UTF8 = Charset("UTF-8")
GB18030 = Charset("GB18030")
)
func ConvertByte2String(byte []byte, charset Charset) string {
var str string
switch charset {
case GB18030:
decodeBytes, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
str = string(decodeBytes)
case UTF8:
fallthrough
default:
str = string(byte)
}
return str
}
func execCommand(command ,execName,arg string)(result string){
out, err := exec.Command(execName,arg,command).Output()
var builder strings.Builder
if err == nil{
// 拼接字符串
res := ConvertByte2String(out,GB18030)
builder.WriteString(res)
}else {
res := fmt.Sprintf("'%s' not found\n",command)
builder.WriteString(res)
}
result = builder.String()
return result
}
func handle(conn net.Conn){
// 不要忘记关闭conn
defer conn.Close()
// 开始处理conn
// 1.创建一个网络io对象
ncReader := bufio.NewReader(conn)
var commandRes string
// 2.持续接收命令
for {
// 3.接收消息(客户端发来的命令)
// 返回字符串和nil
command, err := proto.Decode(ncReader)
// 4.判断是否出错
if err != nil{
if err == io.EOF {
return
}
log.Println(err)
}
// 5.拿到command,执行输出的结果为out
// 返回一个切片,如果命令运行失败,会返回
// 判断当前平台
if runtime.GOOS == "windows" {
commandRes = execCommand(command,"cmd","/c")
} else {
commandRes = execCommand(command,"/bin/sh","-c")
}
// 6.把命令执行的结果发送给客户端
data, err := proto.Encode(commandRes)
// 如果封包失败,退出
if err != nil {
log.Print(err)
os.Exit(1)
}
// 发送封包好的数据
// 命令执行是没有问题,即data是ok的
conn.Write(data)
}
}
func main() {
port := flag.Int("p",8889,"端口")
flag.Parse()
hostPort := fmt.Sprintf(":%d",*port)
// 开启监听
server,err := net.Listen("tcp",hostPort)
// 判断监听是否成功
if err != nil{
log.Print(err)
os.Exit(1) // 1 有错误退出
}
defer server.Close() // 退出别忘记关闭链接
// 死循环 开始接收链接
for {
conn,err := server.Accept()
if err != nil{
os.Exit(1) // 1 有错误退出
}
// 开启 goroutine 处理conn
go handle(conn)
}
}