TCP/IP(Transmission Control Protocol/Internet Protocol) 即傳輸控制協議/網間協議,是一種面向鏈接(鏈接導向)的、可靠的、基於字節流的傳輸層(Transport layer)通訊協議,由於是面向鏈接的協議,數據像水流同樣傳輸,會存在黏包問題。瀏覽器
一個TCP服務端能夠同時鏈接不少個客戶端,例如世界各地的用戶使用本身電腦上的瀏覽器訪問淘寶網。由於Go語言中建立多個goroutine實現併發很是方便和高效,因此咱們能夠每創建一次連接就建立一個goroutine去處理。併發
TCP服務端程序的處理流程:tcp
咱們使用Go語言的net包實現的TCP服務端代碼以下spa
package main import ( "bufio" "fmt" "net" ) // server // 監聽端口 // 接收客戶端請求創建連接 // 建立goroutine處理連接 func process(conn net.Conn) { defer conn.Close() // 關閉鏈接 for { reader := bufio.NewReader(conn) var buf [128]byte n, err := reader.Read(buf[:]) // 讀取數據 if err != nil { fmt.Println("read from client failed, err:", err) break } recvStr := string(buf[:n]) fmt.Println("收到client端發來的數據:", recvStr) recvStr += "\tto" conn.Write([]byte(recvStr)) // 發送數據 } } func main() { listen, err := net.Listen("tcp", "127.0.0.1:20000") if err != nil { fmt.Println("listen failed, err:", err) return } for { conn, err := listen.Accept() // 創建鏈接 if err != nil { fmt.Println("accept failed, err:", err) continue } go process(conn) // 啓動一個goroutine處理鏈接 } }
一個TCP客戶端進行TCP通訊的流程以下:code
使用Go語言的net包實現的TCP客戶端代碼以下:server
package main import ( "bufio" "fmt" "net" "os" "strings" ) // client // 創建與服務端的連接 // 進行數據收發 // 關閉連接 func main() { conn, err := net.Dial("tcp", "127.0.0.1:20000") if err != nil { fmt.Println("err :", err) return } defer conn.Close() // 關閉連接 inputReader := bufio.NewReader(os.Stdin) for { input, _ := inputReader.ReadString('\n') // 讀取用戶輸入 inputInfo := strings.Trim(input, "\r\n") if strings.ToUpper(inputInfo) == "Q" { // 若是輸入q就退出 return } _, err = conn.Write([]byte(inputInfo)) // 發送數據 if err != nil { return } buf := [512]byte{} n, err := conn.Read(buf[:]) if err != nil { fmt.Println("recv failed, err:", err) return } fmt.Println(string(buf[:n])) } }