Skip to content

Instantly share code, notes, and snippets.

@kavinyao
Created July 27, 2018 08:46
Show Gist options
  • Save kavinyao/e2ec260b91aec77348fa510a83516ba7 to your computer and use it in GitHub Desktop.
Save kavinyao/e2ec260b91aec77348fa510a83516ba7 to your computer and use it in GitHub Desktop.
Go practice with JSON, TCP networking, file system, command-line flag parsing
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"net"
"os"
"strconv"
)
func main() {
port := flag.Int("port", 5555, "Server port")
flag.Parse()
if *port == 0 {
fmt.Println("Port is not specified!")
os.Exit(1)
}
conn, err := net.Dial("tcp", "localhost:" + strconv.Itoa(*port))
if err != nil {
fmt.Println("net.Dial() returned", err.Error())
os.Exit(1)
}
defer conn.Close()
// deliberate small size to do batched read
buff_size := 32
tmp_buff := make([]byte, buff_size)
var data_buff []byte
var read_complete bool
for {
n, err := conn.Read(tmp_buff)
if err != nil {
fmt.Println("conn.Read() returned", err.Error())
if err == io.EOF {
read_complete = true
} else {
os.Exit(1)
}
}
fmt.Println("Read", n, "bytes")
data_buff = append(data_buff, tmp_buff[:n]...)
if read_complete {
break
}
}
var files []string
err = json.Unmarshal(data_buff, &files)
if err != nil {
fmt.Println("json.Unmarshal() returned", err.Error())
os.Exit(1)
}
fmt.Println(files)
}
package main
import (
"encoding/json"
"flag"
"fmt"
"net"
"os"
"path/filepath"
"strings"
)
type PathTraverser struct {
files []string
}
func (pt *PathTraverser) Traverse(root string) error {
os.Chdir(root)
return filepath.Walk(".", pt.visit)
}
func (pt *PathTraverser) visit(path string, info os.FileInfo, err error) error {
fmt.Println("Visited", path)
if strings.HasPrefix(info.Name(), ".") {
fmt.Println("Skipping", path)
return nil
}
pt.files = append(pt.files, path)
return nil
}
func handleRequest(files []string, conn net.Conn) error {
defer conn.Close()
j, err := json.Marshal(files)
if err != nil {
fmt.Println("json.Marshal() returned", err.Error())
return err
}
if _, err := conn.Write(j); err != nil {
fmt.Println("conn.Write() returned", err.Error())
return err
}
return nil
}
func main() {
flag.Parse()
root := flag.Arg(0)
pt := PathTraverser{}
err := pt.Traverse(root)
if err != nil {
fmt.Println("pt.Traverse() returned", err.Error())
os.Exit(1)
}
listen, err := net.Listen("tcp", "localhost:5555")
if err != nil {
fmt.Println("net.Listen() returned", err.Error())
os.Exit(1)
}
defer listen.Close()
for {
conn, err := listen.Accept()
if err != nil {
fmt.Println("listen.Accept() returned", err.Error())
os.Exit(1)
}
go handleRequest(pt.files, conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment