아래는 go를 이용한 간단한 TCP/IP Echo Server 예제 입니다.
관리 용이성을 위해 서버와 클라이언트를 한 코드에 넣었습니다.
package main
import (
"bufio"
"fmt"
"net"
"os"
"time"
)
func main() {
send := make(chan string)
quit := make(chan string)
addr, err := net.ResolveTCPAddr("tcp", ":9000")
ln, err := net.ListenTCP("tcp", addr)
if err != nil {
fmt.Println(err.Error())
return;
}
go runServer(ln, quit)
time.Sleep(time.Duration(1) * time.Second)
conn, err := net.Dial("tcp", "127.0.0.1:9000")
if err != nil {
fmt.Println(err.Error())
return;
}
go runClient(conn, quit)
go runScan(send, quit)
stop := false
for !stop {
fmt.Println("main loop ...")
select {
case text, ok := <- send:
if !ok {
ln.Close()
conn.Close()
stop = true
}
conn.Write([]byte(text))
case err := <- quit:
fmt.Println(err)
stop = true
}
}
fmt.Println("complete.")
}
func runScan(send chan string, quit chan string) {
fmt.Println("runScan begin.")
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if text == "." {
close(send)
break
}
send <- text
}
fmt.Println("runScan end.")
}
func runServer(ln *net.TCPListener, quit chan string) {
fmt.Println("runServer begin.")
for {
conn, err := ln.Accept()
if err != nil {
quit <- err.Error()
break
}
go runSession(conn, quit)
}
fmt.Println("runServer end.")
}
func runSession(conn net.Conn, quit chan string) {
fmt.Println("runSession begin.")
buf := make([]byte, 1024)
for {
size, err := conn.Read(buf)
if err != nil || size == 0 {
quit <- err.Error()
break
}
_, err = conn.Write(buf[:size])
if err != nil {
quit <- err.Error()
break
}
}
fmt.Println("runSession end.")
}
func runClient(conn net.Conn, quit chan string) {
fmt.Println("runClient begin.")
buf := make([]byte, 1024)
for {
size, err := conn.Read(buf)
if err != nil {
quit <- err.Error()
break
}
fmt.Println(string(buf[:size]))
}
fmt.Println("runClient end.")
}