最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言如何實現(xiàn)TCP通信詳解

 更新時間:2023年01月07日 11:46:29   作者:yuzhang_zy  
go里面實現(xiàn)tcp沒有像之前寫的C++那些那么麻煩,在C++里面要先創(chuàng)建套接字,然后綁定ip地址,go里面直接就一個函數(shù)建立套接字,然后在進行通信就可以了,下面這篇文章主要給大家介紹了關于Go語言如何實現(xiàn)TCP通信的相關資料,需要的朋友可以參考下

前言

TCP協(xié)議為傳輸控制協(xié)議,TCP協(xié)議有以下幾個特點:

1. TCP是面向連接的傳輸層協(xié)議;

2. 每條TCP連接只能有兩個端點,每條TCP連接是點到點的通信;

3. TCP提供可靠的交付服務,保證傳送的數(shù)據(jù)無差錯,不丟失,不重要且有序;

4. TCP提供全雙工通信,允許雙方在任何時候都能發(fā)送數(shù)據(jù),為此TCP連接的兩端都設有發(fā)送緩存和接收緩存,用來臨時存放雙向通信的數(shù)據(jù);

5. TCP是面向字節(jié)流的;

發(fā)送緩存用來暫存以下數(shù)據(jù):

① 發(fā)送應用程序傳送給發(fā)送方TCP準備發(fā)送的數(shù)據(jù);

② TCP已發(fā)送但尚未收到確認的數(shù)據(jù);

接收緩存用來暫存以下數(shù)據(jù):

① 按序到達但尚未被接收應用程序讀取的數(shù)據(jù);

② 不按序到達的數(shù)據(jù);

因為是面向連接的協(xié)議,數(shù)據(jù)像水流一樣傳輸,會存在黏包問題。

TCP連接

一個TCP服務端可以同時連接很多個客戶端,Go語言可以使用go關鍵字開啟goroutine,每建立一個連接就創(chuàng)建一個goroutine,這樣可以并發(fā)執(zhí)行每一個創(chuàng)建的連接,tcp服務端主要的處理流程有:1. 監(jiān)聽端口;2. 接收客戶端請求創(chuàng)建tcp連接;3. 使用go關鍵字開啟goroutine處理每一個建立的連接,收發(fā)數(shù)據(jù);4. 關閉連接;tcp客戶端主要的處理流程有:1. 建立與服務端的連接;2. 收發(fā)數(shù)據(jù);3. 關閉連接;關于tcp通信我們一般會使用到bufio,net,strings,os包,其中bufio包主要用來做輸入輸出數(shù)據(jù)的緩存,bufio.NewReader()函數(shù)可以傳遞os.Stdin類型(任何實現(xiàn)了io.Reader接口中的read()方法都可以作為參數(shù)傳遞進來,通常是傳遞一個實現(xiàn)了io.Reader接口中的read()方法的結(jié)構體或者是結(jié)構體指針),os.Stdin為標準輸入,我們可以接受讀取從控制臺輸入的數(shù)據(jù),os.NewReader()函數(shù)返回的是一個新的帶有4096 byte大小緩沖區(qū)的Reader結(jié)構體指針類型,通過Reader結(jié)構體指針類型我們就可以調(diào)用很多的方法,比如可以調(diào)用ReadString(delim byte) (string,error)方法,ReadString方法可以一直從標準輸入中讀取數(shù)據(jù),直到遇到指定的終止符號delim,并且讀取的內(nèi)容會包含當前的delim,所以bufio包主要用來對輸入和輸出的數(shù)據(jù)進行緩沖;net包主要是連接的監(jiān)聽、創(chuàng)建,以及連接數(shù)據(jù)的讀取和寫入(例如tcp,udp等網(wǎng)絡編程)等相關工作,tcp服務端中可以使用一個process()函數(shù)傳遞一個net.Conn類型也即*net.TCPConn類型的變量conn(TCPConn結(jié)構體實現(xiàn)了Conn接口),*TCPConn類型那么就可以調(diào)用很多的方法,因為我們需要從tcp連接中讀取客戶端或者是服務端發(fā)送的數(shù)據(jù),所以可以調(diào)用*TCPConn類型的read()方法讀取tcp連接的數(shù)據(jù),然后輸出數(shù)據(jù)即可,服務端可以使用net.Listen()函數(shù)監(jiān)聽連接,使用Accept()方法建立tcp連接,客戶端則可以使用net.Dial()連接創(chuàng)建的tcp連接,使用conn接口的實現(xiàn)*TCPConn(Dial()方法的返回值就是*TCPConn類型)調(diào)用conn的read()方法將讀取tcp連接的內(nèi)容,write()方法將數(shù)據(jù)寫入到tcp連接中;strings包主要是對讀取到的數(shù)據(jù)的字符串形式進行處理,比如去除掉字符串的一些符號等等。

下面的代碼需要先運行服務端的代碼,再運行客戶端的代碼:

TCP服務端

package main
 
import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)
 
// TCP 服務端
func process(conn net.Conn) {
	// 函數(shù)執(zhí)行完之后關閉連接
	defer conn.Close()
	// 輸出主函數(shù)傳遞的conn可以發(fā)現(xiàn)屬于*TCPConn類型, *TCPConn類型那么就可以調(diào)用*TCPConn相關類型的方法, 其中可以調(diào)用read()方法讀取tcp連接中的數(shù)據(jù)
	fmt.Printf("服務端: %T\n", conn)
	for {
		var buf [128]byte
		// 將tcp連接讀取到的數(shù)據(jù)讀取到byte數(shù)組中, 返回讀取到的byte的數(shù)目
		n, err := conn.Read(buf[:])
		if err != nil {
			// 從客戶端讀取數(shù)據(jù)的過程中發(fā)生錯誤
			fmt.Println("read from client failed, err:", err)
			break
		}
		recvStr := string(buf[:n])
		fmt.Println("服務端收到客戶端發(fā)來的數(shù)據(jù):", recvStr)
		// 由于是tcp連接所以雙方都可以發(fā)送數(shù)據(jù), 下面接收服務端發(fā)送的數(shù)據(jù)這樣客戶端也可以收到對應的數(shù)據(jù)
		inputReader := bufio.NewReader(os.Stdin)
		s, _ := inputReader.ReadString('\n')
		t := strings.Trim(s, "\r\n")
		// 向當前建立的tcp連接發(fā)送數(shù)據(jù), 客戶端就可以收到服務端發(fā)送的數(shù)據(jù)
		conn.Write([]byte(t))
	}
}
 
func main() {
	// 監(jiān)聽當前的tcp連接
	listen, err := net.Listen("tcp", "127.0.0.1:20000")
	fmt.Printf("服務端: %T=====\n", listen)
	if err != nil {
		fmt.Println("listen failed, err:", err)
		return
	}
	for {
		conn, err := listen.Accept() // 建立連接
		fmt.Println("當前建立了tcp連接")
		if err != nil {
			fmt.Println("accept failed, err:", err)
			continue
		}
		// 對于每一個建立的tcp連接使用go關鍵字開啟一個goroutine處理
		go process(conn) 
	}
}

TCP客戶端

package main
 
import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)
 
func main() {
	// 連接到服務端建立的tcp連接
	conn, err := net.Dial("tcp", "127.0.0.1:20000")
	// 輸出當前建Dial函數(shù)的返回值類型, 屬于*net.TCPConn類型
	fmt.Printf("客戶端: %T\n", conn)
	if err != nil {
		// 連接的時候出現(xiàn)錯誤
		fmt.Println("err :", err)
		return
	}
	// 當函數(shù)返回的時候關閉連接
	defer conn.Close() 
	// 獲取一個標準輸入的*Reader結(jié)構體指針類型的變量
	inputReader := bufio.NewReader(os.Stdin)
	for {
		// 調(diào)用*Reader結(jié)構體指針類型的讀取方法
		input, _ := inputReader.ReadString('\n') // 讀取用戶輸入
		// 去除掉\r \n符號
		inputInfo := strings.Trim(input, "\r\n")
		// 判斷輸入的是否是Q, 如果是Q則退出
		if strings.ToUpper(inputInfo) == "Q" { // 如果輸入q就退出
			return
		}
		_, err = conn.Write([]byte(inputInfo)) // 發(fā)送數(shù)據(jù)
		if err != nil {
			return
		}
		buf := [512]byte{}
		// 讀取服務端發(fā)送的數(shù)據(jù)
		n, err := conn.Read(buf[:])
		if err != nil {
			fmt.Println("recv failed, err:", err)
			return
		}
		fmt.Println("客戶端接收服務端發(fā)送的數(shù)據(jù): ", string(buf[:n]))
	}
}

總結(jié)

到此這篇關于Go語言如何實現(xiàn)TCP通信的文章就介紹到這了,更多相關Go語言TCP通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Golang實現(xiàn)可重入鎖的示例代碼

    Golang實現(xiàn)可重入鎖的示例代碼

    可重入鎖指的是同一個線程外層函數(shù)獲得鎖之后,內(nèi)層遞歸函數(shù)仍然能獲取該鎖的代碼,在同一個線程在外層方法獲取鎖的時候,在進入內(nèi)層方法會自動獲取鎖。本文將用Golang實現(xiàn)可重入鎖,需要的可以參考一下
    2022-05-05
  • 利用go語言實現(xiàn)查找二叉樹中的最大寬度

    利用go語言實現(xiàn)查找二叉樹中的最大寬度

    這篇文章主要介紹了利用go語言實現(xiàn)查找二叉樹中的最大寬度,文章圍繞主題展開詳細介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Golang自動追蹤GitHub上熱門AI項目

    Golang自動追蹤GitHub上熱門AI項目

    這篇文章主要為大家介紹了Golang自動追蹤GitHub上熱門AI項目,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Golang中的自定義函數(shù)詳解

    Golang中的自定義函數(shù)詳解

    函數(shù)構成代碼執(zhí)行的邏輯結(jié)構。在Go語言中,函數(shù)的基本組成為:關鍵字func、函數(shù)名、參數(shù)列表、返回值、函數(shù)體和返回語句。
    2018-10-10
  • Go實現(xiàn)Redis連接池方法

    Go實現(xiàn)Redis連接池方法

    為了更深入了解golang連接池的實現(xiàn),自已又重寫了一遍連接池。文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • gin解析json格式的數(shù)據(jù)出錯的處理方案

    gin解析json格式的數(shù)據(jù)出錯的處理方案

    這篇文章主要介紹了gin解析json格式的數(shù)據(jù)出錯的處理方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Go語言中的Struct結(jié)構體

    Go語言中的Struct結(jié)構體

    這篇文章介紹了Go語言中的Struct結(jié)構體,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • 一文讀懂go中semaphore(信號量)源碼

    一文讀懂go中semaphore(信號量)源碼

    這篇文章主要介紹了一文讀懂go中semaphore(信號量)源碼的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Golang pipe在不同場景下遠程交互

    Golang pipe在不同場景下遠程交互

    這篇文章主要介紹了Golang pipe在不同場景下遠程交互,pipe實現(xiàn)從一個進程重定向至另一個進程,它是雙向數(shù)據(jù)通道,用于實現(xiàn)進行間通信
    2023-03-03
  • golang使用mapstructure解析json

    golang使用mapstructure解析json

    mapstructure?是一個?Go?庫,用于將通用映射值解碼為結(jié)構,這篇文章主要來和大家介紹一下golang如何使用mapstructure解析json,需要的可以參考下
    2023-12-12

最新評論

巨鹿县| 滦平县| 岳普湖县| 仁寿县| 曲水县| 纳雍县| 西昌市| 仙桃市| 寿阳县| 买车| 呼图壁县| 额敏县| 彭山县| 山阳县| 宝清县| 织金县| 库伦旗| 深圳市| 英吉沙县| 萝北县| 左权县| 永安市| 甘孜县| 阳高县| 图们市| 屏边| 泰宁县| 朔州市| 常州市| 东乡县| 儋州市| 永登县| 建瓯市| 汝阳县| 临海市| 炎陵县| 万安县| 邹城市| 常州市| 铜梁县| 漳浦县|