socket簡單通訊

base:

TCP/IP(Transmission Control Protocol/Internet Protocol) 即傳輸控制協議/網間協議,是一種面向鏈接(鏈接導向)的、可靠的、基於字節流的傳輸層(Transport layer)通訊協議,由於是面向鏈接的協議,數據像水流同樣傳輸,會存在黏包問題。瀏覽器

TCP-server:

一個TCP服務端能夠同時鏈接不少個客戶端,例如世界各地的用戶使用本身電腦上的瀏覽器訪問淘寶網。由於Go語言中建立多個goroutine實現併發很是方便和高效,因此咱們能夠每創建一次連接就建立一個goroutine去處理。併發

TCP服務端程序的處理流程:tcp

  1. 監聽端口
  2. 接收客戶端請求創建連接
  3. 建立goroutine處理連接。

咱們使用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-client

一個TCP客戶端進行TCP通訊的流程以下:code

  1. 創建與服務端的連接
  2. 進行數據收發
  3. 關閉連接

使用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]))
    }
}
相關文章
相關標籤/搜索