跳至主要内容

[course] Web Development with Go

Create Your Own Server

Create and Write to Connection

  • 使用 net.Listen() 來建立監聽 8080 tcp 連線
  • li.Accept() 中可以拿到 Conn,其中 Conn 是一個帶有 ReadWriteClose 的 interface
  • conn 傳入 io.WriteStringfmt.Fprintlnfmt.Fprintf 都可以寫入這個 connection
func main() {
// STEP 1: 使用 `net.Listen` 來建立監聽 8080 tcp 連線
li, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalln("err")
}
defer li.Close()

for {
// STEP 2: li.Accept 可以讀取監聽到的內容
conn, err := li.Accept()
if err != nil {
log.Println(err)
continue
}

// STEP 3: Write to Connection
io.WriteString(conn, "\nHello from TCP server\n")
fmt.Fprintln(conn, "How is your day?")
fmt.Fprintf(conn, "%v", "Well, I hope!")

conn.Close()
}
}

Read from connection using bufio.Scanner

使用 bufio.NewScanner 可以讀取 request

func main() {
li, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalln("err")
}
defer li.Close()

for {
conn, err := li.Accept()
if err != nil {
log.Println(err)
continue
}

go handle(conn)
}
}

func handle(conn net.Conn) {
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
fmt.Println(ln)
}
defer conn.Close()
}

Read from & write to connection

只需要使用前面提到,能夠撰寫 conn 的方法:

func handle(conn net.Conn) {
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
fmt.Println(ln)
fmt.Fprintf(conn, "I heard you say: %s \n\n", ln)
}
defer conn.Close()
}

如果我們使用 telnet localhost 8080 來與 server 建立連線,並從中輸入內容:

read and write

另外,為了避免 connection 建立後,server 一直等請求而沒有辦法中斷連線,可以使用 conn.SetDeadline

func handle(conn net.Conn) {
err := conn.SetDeadline(time.Now().Add(5 * time.Second))
if err != nil {
log.Fatalln("CONN TIMEOUT")
}
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
fmt.Println(ln)
fmt.Fprintf(conn, "I heard you say: %s \n\n", ln)
}

defer conn.Close()

fmt.Println("CONN CLOSE")
}

建立 TCP 連線

傳送資料給 server,並等待 server 回應:

func main() {
// 建立 TCP 連線
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatalln(err)
}
defer conn.Close()

// Send Request to server
fmt.Fprintln(conn, "I dialed you")

// Get Response from server
bs, err := io.ReadAll(conn)
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(bs))
}

read and write