乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      go語言系列-TCP編程

       頭號碼甲 2020-05-22

      TCP編程

      Go的主要設(shè)計目標(biāo)之一就是面向大規(guī)模后端服務(wù)程序,網(wǎng)絡(luò)通信這塊是服務(wù)端,程序必不可少也是至關(guān)重要的一部分

      網(wǎng)絡(luò)編程基本介紹

      網(wǎng)絡(luò)編程有兩種

      TCP socket編程,是網(wǎng)絡(luò)編程的主流。之所以叫Tcp socket 編程,是因為底層基于Tcp/ip協(xié)議的。比如:QQ聊天

      b/s結(jié)構(gòu)的http編程,使用瀏覽器去訪問服務(wù)器時,使用的就是http協(xié)議,而http底層依舊是用tcp socket實現(xiàn)的。比如:京東商城【屬于go web開發(fā)范疇】

      計算機間要相互通訊,必須要是用網(wǎng)線、網(wǎng)卡或者無線網(wǎng)卡

      協(xié)議(tcp/ip)

      TCP/IP(Transmission Control Protocol/Internet Protocol)的簡寫,中文譯名為傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,又叫網(wǎng)絡(luò)通訊協(xié)議,這個協(xié)議是Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),簡單地說,就是由網(wǎng)絡(luò)層的IP協(xié)議和傳輸層的TCP協(xié)議組成的

      OSI與TCP/IP參考模型

      書籍推薦《tcp/ip協(xié)議3卷》

      IP地址

      每個internet上的主機和路由器都有一個ip地址,它包括網(wǎng)絡(luò)號和主機號,ip地址有ipv4(32位)或者ipv6(128位)可以ipconfig查看

      端口(port)-介紹

      這里所指的端口不是指物理意義上的端口,而是特指TCP/IP協(xié)議中的端口,是邏輯意義上的端口

      如果把IP地址比作一間房子,端口就是出入這間房子的門。真正的房子只有幾個門,但是IP地址的端口可以有65536(即:256 × 256)個之多!端口是通過端口號來標(biāo)記的,端口號只有整數(shù),范圍是從0到65535(256 × 256 - 1)

      端口-分類

      0號是保留端口

      1 - 1024 是固定端口(程序員不要使用

      ? 又叫有名端口,即被某些程序固定使用,一般程序員不使用

      ? 22:SSH遠(yuǎn)程登陸協(xié)議 23:telnet使用 21:ftp使用 25:smtp使用 80:iis使用 7:echo 使用

      1025 - 65535 是動態(tài)端口

      ? 這些端口,程序員可以使用

      端口-使用注意

      1. 在計算機(尤其是服務(wù)器)要盡可能少開端口

      2. 一個端口只能被一個程序監(jiān)聽

      3. 如果使用netstat -an 可以查看本機有哪些端口在監(jiān)聽

      4. 可以使用netstat -anb 來查看監(jiān)聽端口的pid,再結(jié)合任務(wù)管理器關(guān)閉不安全的端口

      tcp socket編程的客戶端和服務(wù)端

      tcp socket 編程,簡稱socket編程,下圖為Go socket編程中客戶端和服務(wù)器端的網(wǎng)絡(luò)分布

      tcp socket編程的快速入門

      服務(wù)端的處理流程

      1. 監(jiān)聽端口8888

      2. 接收客戶端的tcp鏈接,建立客戶端和服務(wù)器端的鏈接

      3. 創(chuàng)建goroutine,處理該鏈接的請求(通??蛻舳藭ㄟ^鏈接發(fā)送請求包)

      客戶端的處理流程

      1. 建立與服務(wù)端的鏈接

      2. 發(fā)送請求數(shù)據(jù)[終端],接收服務(wù)器端返回的結(jié)果數(shù)據(jù)

      3. 關(guān)閉鏈接

      簡單的程序示意圖

      代碼實現(xiàn)

      服務(wù)器端功能

      1.編寫一個服務(wù)器端程序,在8888端口監(jiān)聽

      2.可以和多個客戶端創(chuàng)造鏈接

      3.鏈接成功后,客戶端可以發(fā)送數(shù)據(jù),服務(wù)器端接受數(shù)據(jù),并顯示在終端上

      4.先使用telnet來測試,然后編寫客戶端程序來測試

      import (
         "fmt"
         "net" //做網(wǎng)絡(luò)socket開發(fā)時,net包含有我們需要所有的方法和函數(shù)
         _"io"
      )
      
      func process(conn net.Conn)  {
         //這里我們循環(huán)的接受客戶端發(fā)送的數(shù)據(jù)
         defer conn.Close() //關(guān)閉conn
         for {
            //創(chuàng)建一個新的切片
            buf := make([]byte,1024)
            //conn.Read(buf)
            //1. 等待客戶端通過conn發(fā)送信息
            //2. 如果客戶端沒有write[發(fā)送],那么協(xié)程就阻塞在這里
            fmt.Printf("服務(wù)器在等待客戶端%s 發(fā)送信息\n", conn.RemoteAddr().String())
            n, err := conn.Read(buf) //從conn讀取
            if err != nil {
               fmt.Printf("客戶端退出 err = %v", err)
               return // !!!
            }
            //3. 顯示客戶端發(fā)送的內(nèi)容到服務(wù)器的終端
            fmt.Print(string(buf[:n]))
         }
      }
      func main()  {
         fmt.Println("服務(wù)器開始監(jiān)聽...")
         //net.Listen("tcp", "0.0.0.0:8888")
         //1. tcp 表示使用網(wǎng)絡(luò)協(xié)議是tcp
         //2. 0.0.0.0:8888 表示在本地監(jiān)聽 8888端口
         listen, err := net.Listen("tcp","0.0.0.0:8888")
         if err != nil {
            fmt.Println("listen err = ", err)
            return
         }
         defer listen.Close() // 延時關(guān)閉listen
         //循環(huán)等待客戶端來鏈接我
         for {
            //等待客戶端鏈接
            fmt.Println("等待客戶端來鏈接...")
            conn, err := listen.Accept()
            if err != nil {
               fmt.Println("Accept() err =", err)
            } else {
               fmt.Printf("Accept() suc con = %v 客戶端 ip = %v\n", conn, conn.RemoteAddr().String())
            }
            //這里準(zhǔn)備其一個協(xié)程,為客戶端服務(wù)
            go process(conn)
         }
         //fmt.Printf("liaten suc = %v\n",listen)
      }
      

      客戶端功能:

      1.編寫一個客戶端端程序,能鏈接到服務(wù)器端的8888端口

      2.客戶端可以發(fā)送單行數(shù)據(jù),然后就退出

      3.能通過終端輸入數(shù)據(jù)(輸入一行發(fā)送一行),并發(fā)送給服務(wù)器端

      4.在終端輸入exit,表示退出程序

      import (
         "bufio"
         "fmt"
         "net"
         "os"
      )
      
      func main()  {
         conn, err := net.Dial("tcp", "0.0.0.0:8888")
         if err != nil {
            fmt.Println("client dial err = ", err)
            return
         }
         //功能一:客戶端可以發(fā)送單行數(shù)據(jù),然后就退出
         reader := bufio.NewReader(os.Stdin) //os.Stdin 代表標(biāo)準(zhǔn)輸入[終端]
         //從終端讀取一行用戶輸入,并準(zhǔn)備發(fā)送給服務(wù)器
         line, err := reader.ReadString('\n')
         if err != nil {
            fmt.Println("readString err = ", err)
         }
         //再將line發(fā)送給服務(wù)器
         n, err := conn.Write([]byte(line))
         if err != nil {
            fmt.Println("conn.Write err =", err)
         }
         fmt.Printf("客戶端發(fā)送了 %d 字節(jié)的數(shù)據(jù),并退出", n)
      }
      

      驗證 先執(zhí)行服務(wù)端程序 再執(zhí)行客戶端程序

      服務(wù)器開始監(jiān)聽...
      等待客戶端來鏈接...
      Accept() suc con = &{{0xc00007e2c0}} 客戶端 ip = 127.0.0.1:65393
      等待客戶端來鏈接...
      服務(wù)器在等待客戶端127.0.0.1:65393 發(fā)送信息
      

      對客戶端進行改進

      import (
         "bufio"
         "fmt"
         "net"
         "os"
         "strings"
      )
      
      func main()  {
         conn, err := net.Dial("tcp", "0.0.0.0:8888")
         if err != nil {
            fmt.Println("client dial err = ", err)
            return
         }
         //功能一:客戶端可以發(fā)送單行數(shù)據(jù),然后就退出
         reader := bufio.NewReader(os.Stdin) //os.Stdin 代表標(biāo)準(zhǔn)輸入[終端]
         for {
            //從終端讀取一行用戶輸入,并準(zhǔn)備發(fā)送給服務(wù)器
            line, err := reader.ReadString('\n')
            if err != nil {
               fmt.Println("readString err = ", err)
            }
            //如果用戶輸入的是exit就退出
            line = strings.Trim(line, " \r\n")
            if line == "exit" {
               fmt.Println("客戶端退出...")
               break
            }
      
            //再將line發(fā)送給服務(wù)器
            _, err = conn.Write([]byte(line + "\n"))
            if err != nil {
               fmt.Println("conn.Write err =", err)
            }
         }
         //fmt.Printf("客戶端發(fā)送了 %d 字節(jié)的數(shù)據(jù),并退出", n)
      }
      

      驗證

      hello zisefeizhu
      
      服務(wù)器開始監(jiān)聽...
      等待客戶端來鏈接...
      Accept() suc con = &{{0xc0000902c0}} 客戶端 ip = 127.0.0.1:49248
      等待客戶端來鏈接...
      服務(wù)器在等待客戶端127.0.0.1:49248 發(fā)送信息
      hello zisefeizhu
      服務(wù)器在等待客戶端127.0.0.1:49248 發(fā)送信息
      

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多