2017年6月30日 星期五

Golang : TCP Connection

使用 golang 的 net 功能建立 tcp 的 server 和 client 筆記。
要建立 tcp 伺服器,需要先建立 Listen 監聽器,監聽後需要進入迴圈,等待新的 Client 端進行連線,迴圈中的 Accept() 會進入卡死等待,進入後再用 go routine 開啟新執行緒處理該使用者的行為。

Server

package main

import (
 "net"
 "io"
 "fmt"
 "bufio"
 "time"
)

func main(){
 tcp, err := net.Listen("tcp", ":8080")
 if err != nil{
  panic("tcp listen error!")
 }
 defer tcp.Close()

 for {
  conn, err := tcp.Accept()
  if err != nil{
   panic("can't accept this user.")
  }
                
  io.WriteString(conn, "\n Hello World!")
  fmt.Fprintf(conn, "\n This is TCP server\n\n\n\n")
  
  go handler(conn)
 }
}

func handler (conn net.Conn){

        //setup 10 second then disconnect.
 err := conn.SetDeadline(time.Now().Add(10 * time.Second))
 if err != nil{
  panic("Deadline.")
 }
 
        //scan this client thread, when receive client message, then printout. 
 scanner := bufio.NewScanner(conn)
 for scanner.Scan(){
  ln := scanner.Text()
  fmt.Println(ln)
 }

 defer conn.Close()
}

可以使用 telnet localhost 8080 指令開啟連接,測試 tcp server。


Client

然後, Client 端的設計,一樣可以用 Scanner 來等待 server 回應。
package main

import (
 "net"
 "bufio"
 "fmt"
)


func main(){
 tcp, err := net.Dial("tcp", "localhost:8080")

 if err != nil{
  panic("tcp connection error!")
 }

 scanner := bufio.NewScanner(tcp)
 for scanner.Scan(){
  ln := scanner.Text()
  fmt.Println(ln)
 }

 defer tcp.Close()

}

HTTP Response

要回應到瀏覽器 http 的 tcp 設計,只要回應標頭、類型和長度就可以了,直接加在 tcp server 任一處做回應:
func responseHTTP(conn net.Conn){
 body := "<p>Hello World</p>"
 fmt.Fprintf(conn, "HTTP/1.1 200 OK\r\n")
 fmt.Fprintf(conn, "Content-Length: %d\r\n", len(body))
 fmt.Fprintf(conn, "Content-Type: text/html\r\n")
 fmt.Fprintf(conn, "\r\n")
 fmt.Fprintf(connt, body)
}


Reference:
https://golang.org/pkg/net/

沒有留言:

張貼留言

© Mac Taylor, 歡迎自由轉貼。
Background Email Pattern by Toby Elliott
Since 2014