-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
104 lines (92 loc) · 1.99 KB
/
main.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
package main
import (
"bufio"
_ "embed"
"fmt"
"log"
"net"
"os"
"strconv"
"strings"
"time"
)
//go:embed version.txt
var version string
var (
port int = 43210
workerID int
hostname string
)
func main() {
if len(os.Args) > 1 {
v, err := strconv.Atoi(os.Args[1])
if err != nil {
log.Fatal(err)
}
port = v
}
hostname, _ = os.Hostname()
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
log.Fatal(err)
}
log.Printf("%s Listening on port %d...", version, port)
defer l.Close()
for {
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
workerID++
go handle(conn, workerID)
}
}
func handle(c net.Conn, id int) {
log.Printf("%d: starting connection with %v", id, c.RemoteAddr().String())
defer func() {
log.Printf("%d: closing connection with %v", id, c.RemoteAddr().String())
c.Close()
}()
fmt.Fprintf(c, "Welcome to tcpecho on %s:%d\nThis is handler #%d, type '.' to quit\n", hostname, port, id)
rd := bufio.NewScanner(c)
for {
if rd.Scan() {
txt := rd.Text()
if txt == "." {
fmt.Fprintln(c, "Goodbye.")
return
}
do(id, c, txt)
}
}
}
type dooer func(id int, c net.Conn, cmd, args string)
var commands = map[string]dooer{
"date": dateCmd,
"time": timeCmd,
"info": infoCmd,
}
func do(id int, c net.Conn, txt string) {
parts := strings.SplitN(txt, " ", 2)
var args string
if len(parts) > 1 {
args = strings.TrimSpace(parts[1])
}
for cmd, fn := range commands {
if strings.EqualFold(cmd, parts[0]) {
log.Printf("%d: doing '%s'", id, cmd)
fn(id, c, cmd, args)
return
}
}
fmt.Fprintf(c, "unknown command: '%s'\n", parts[0])
}
func dateCmd(id int, c net.Conn, cmd, args string) {
fmt.Fprintf(c, "The date is %s\n", time.Now().Format(time.DateOnly))
}
func timeCmd(id int, c net.Conn, cmd, args string) {
fmt.Fprintf(c, "The time is %s\n", time.Now().Format(time.TimeOnly))
}
func infoCmd(id int, c net.Conn, cmd, args string) {
fmt.Fprintf(c, "You are connecting from %s\n", c.RemoteAddr().String())
}