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

使用Go語言構(gòu)建一個最小可用的TCP交互程序

 更新時間:2026年03月13日 09:46:09   作者:我叫黑大帥  
這篇文章主要為大家詳細介紹了如何使用Go語言構(gòu)建一個最小可用的TCP交互程序,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

Go 網(wǎng)絡(luò)編程實戰(zhàn):構(gòu)建一個最小可用的 TCP 交互程序

TCP 服務(wù)端 和 TCP 客戶端 兩部分,運行后能實現(xiàn):

服務(wù)端:啟動后監(jiān)聽本地 8888 端口,能同時處理多個客戶端的連接(并發(fā));

客戶端:主動連接服務(wù)端,你可以在客戶端輸入任意文字,服務(wù)端會 “原樣返回”(Echo 回聲功能);

交互效果

  • 客戶端輸入 hello → 服務(wù)端返回 【服務(wù)端回聲】hello;
  • 客戶端輸入 ip → 服務(wù)端返回 服務(wù)端回復(fù):127.0.0.1:63341(net.ResolveTCPAddr)
  • 客戶端輸入 exit → 客戶端主動斷開連接,服務(wù)端提示 “客戶端已斷開”。

實例代碼

// server.go
package main

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

// 啟動TCP服務(wù)端
func startTCPServer() {
	// 解析地址
	tcpAddr, err := net.ResolveTCPAddr("tcp", ":8888")
	if err != nil {
		fmt.Printf("解析地址失敗:%v\n", err)
		return
	}

	// 監(jiān)聽端口
	listener, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		fmt.Printf("監(jiān)聽端口失?。?v\n", err)
		return
	}
	defer listener.Close()
	fmt.Println("等待客戶端連接...")

	// 接受客戶端連接
	for {
		conn, err := listener.AcceptTCP() // 阻塞等待新連接
		if err != nil {
			fmt.Printf("接受連接失?。?v\n", err)
			continue
		}
		// 并發(fā)處理每個客戶端連接(避免阻塞其他連接)
		go handleClientConn(conn)
	}
}

// 處理單個客戶端連接
func handleClientConn(conn *net.TCPConn) {
	clientAddr := conn.RemoteAddr().String() // 獲取客戶端地址
	fmt.Printf("客戶端 [%s] 已連接\n", clientAddr)
	defer func() {
		conn.Close()
		fmt.Printf("客戶端 [%s] 已斷開連接\n", clientAddr)
	}()

	// 創(chuàng)建緩沖區(qū)讀取客戶端數(shù)據(jù)
	reader := bufio.NewReader(conn)
	for {
		// 讀取客戶端發(fā)送的數(shù)據(jù)
		msg, err := reader.ReadString('\n')
		if err != nil {
			if err.Error() == "EOF" {
				return
			}
			fmt.Printf("讀取客戶端 [%s] 數(shù)據(jù)失敗:%v\n", clientAddr, err)
			return
		}

		msg = strings.TrimSpace(msg)
		if msg == "exit" {
			return
		}

		// special command: return client address
		var response string
		if msg == "ip" {
			response = clientAddr + "\n"
		} else {
			// 普通回聲響應(yīng)
			response = fmt.Sprintf("【服務(wù)端回聲】%s\n", msg)
		}

		_, err = conn.Write([]byte(response))
		if err != nil {
			fmt.Printf("向客戶端 [%s] 發(fā)送數(shù)據(jù)失?。?v\n", clientAddr, err)
			return
		}
		fmt.Printf("客戶端 [%s] 發(fā)送:%s → 響應(yīng):%s", clientAddr, msg, strings.TrimSpace(response))
	}
}

func main() {
	fmt.Println("啟動服務(wù)...")
	startTCPServer()
}
// client.go
package main
import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)
// 啟動TCP客戶端
func startTCPClient() {
	// 解析服務(wù)端地址
	tcpAddr, err := net.ResolveTCPAddr("tcp", ":8888")
	if err != nil {
		fmt.Printf("解析服務(wù)端地址失?。?v\n", err)
		return
	}
	// 連接服務(wù)端
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		fmt.Printf("連接服務(wù)端失?。?v\n", err)
		return
	}
	defer conn.Close()
	fmt.Println("輸入任意文字發(fā)送(輸入 exit 斷開連接):")
	// 讀取用戶輸入
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("> ")
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Printf("讀取輸入失敗:%v\n", err)
			return
		}
		// 處理退出指令
		input = strings.TrimSpace(input)
		if input == "exit" {
			conn.Write([]byte("exit\n"))
			fmt.Println("已斷開與服務(wù)端的連接")
			return
		}
		// 向服務(wù)端發(fā)送數(shù)據(jù)
		_, err = conn.Write([]byte(input + "\n"))
		if err != nil {
			fmt.Printf("發(fā)送數(shù)據(jù)失?。?v\n", err)
			return
		}
		// 讀取服務(wù)端響應(yīng)
		response, err := bufio.NewReader(conn).ReadString('\n')
		if err != nil {
			fmt.Printf("讀取服務(wù)端響應(yīng)失敗:%v\n", err)
			return
		}
		fmt.Printf("服務(wù)端回復(fù):%s", strings.TrimSpace(response))
	}
}
func main() {
	fmt.Println("啟動客戶端...")
	startTCPClient()
}

基礎(chǔ)概念

Net 包介紹

  • 核心協(xié)議TCP、HTTP、RPC 都是基于 net 包或其上層封裝實現(xiàn)的。
  • 實際用途:日常開發(fā)中,我們更多使用 Gin、gRPC 等框架,直接寫原生 net 包的場景有限。
  • 學(xué)習(xí)價值:理解底層原理,能讓你在排查網(wǎng)絡(luò)問題、調(diào)優(yōu)框架時更有底氣,也能更好地理解 “框架到底幫你做了什么”。

TCP 基本概念

這部分是理論基礎(chǔ),理解了這些,后面的代碼就順理成章了:

數(shù)據(jù)結(jié)構(gòu):TCP 是面向字節(jié)流的協(xié)議,數(shù)據(jù)以流的形式傳輸,沒有天然的消息邊界。

傳輸協(xié)議:可靠、面向連接的傳輸層協(xié)議,通過三次握手建立連接,四次揮手斷開連接。

握手 / 揮手機制

  • 三次握手:確保雙方都具備收發(fā)能力,建立可靠連接。
  • 四次揮手:確保雙方數(shù)據(jù)都傳輸完畢,優(yōu)雅斷開連接。

服務(wù)端流程:監(jiān)聽并接受連接

1.ResolveTCPAddr

作用:將字符串形式的地址(如 "localhost:8088")解析成 *net.TCPAddr 對象。

參數(shù):

  • 網(wǎng)絡(luò)類型:"tcp"
  • 地址字符串:"localhost:8088"

意義:為后續(xù)的監(jiān)聽和連接操作提供統(tǒng)一的地址對象。

2.ListenTCP

作用:在指定的網(wǎng)絡(luò)和地址上啟動監(jiān)聽。

步驟:

  • 使用 ResolveTCPAddr 創(chuàng)建的地址對象。
  • 設(shè)置網(wǎng)絡(luò)協(xié)議為 "tcp"。

返回:一個 net.Listener 接口,用于后續(xù)接受連接。

3.AcceptTCP

  • 作用:從監(jiān)聽隊列中接受一個新的客戶端連接。
  • 返回:一個 net.Conn 接口,代表與客戶端的連接。
  • 注意:這是一個阻塞操作,直到有新連接到來或發(fā)生錯誤。

4.循環(huán)監(jiān)聽新連接

  • 核心模式:在一個無限 for 循環(huán)中反復(fù)調(diào)用 AcceptTCP
  • 并發(fā)處理:每次接受新連接后,必須啟動一個新的 goroutine 去處理它(例如 go handleConn(conn)),否則服務(wù)端會阻塞,無法處理下一個連接。
  • 回調(diào)函數(shù):handleConn 就是你之前問的 handler,它負責(zé)與客戶端進行具體的交互。

客戶端流程:主動發(fā)起連接

1.DialTCP

作用:主動向服務(wù)端發(fā)起 TCP 連接。

參數(shù):

  • 本地地址(可選)。
  • 由 ResolveTCPAddr 創(chuàng)建的服務(wù)端地址。

返回:一個 net.Conn 接口,代表與服務(wù)端的連接。

2.發(fā)送接收信息

  • WriteToConn:通過 conn.Write() 方法,將數(shù)據(jù)發(fā)送到服務(wù)端。
  • ReadFromConn:通過 conn.Read() 方法,從服務(wù)端讀取響應(yīng)數(shù)據(jù)。
  • 注意:TCP 是流協(xié)議,需要自己處理粘包問題,比如定義消息長度前綴或特殊分隔符。

3.長連接維護

循環(huán)讀取客戶端輸入:客戶端可以在一個循環(huán)中,不斷讀取用戶輸入并發(fā)送給服務(wù)端,保持連接活躍。

Error 檢測:

  • EOF 異常處理:當 Read 返回 io.EOF 時,說明服務(wù)端已經(jīng)關(guān)閉了連接。
  • 斷開連接通知:客戶端或服務(wù)端都可以主動關(guān)閉連接,另一方需要檢測到并做相應(yīng)清理。

使用場景

TCP 解決「可靠傳輸」的問題,Go 的 net.TCP 讓實現(xiàn)高并發(fā)、高性能的 TCP 服務(wù)變得簡單。

要求「可靠傳輸」的長連接服務(wù)(最核心場景)

  • 物聯(lián)網(wǎng)(IoT)設(shè)備通信:智能家居、工業(yè)傳感器、車載終端等設(shè)備,需要和云端服務(wù)端保持長連接:

    • 設(shè)備定時上報溫濕度、位置、狀態(tài)(數(shù)據(jù)丟包會導(dǎo)致監(jiān)控失效);
    • 云端下發(fā)控制指令(如「開關(guān)燈」「調(diào)整溫度」),需要設(shè)備確認收到;
    • Go 服務(wù)端用 ListenTCP 監(jiān)聽,goroutine 處理每個設(shè)備的 TCPConn,穩(wěn)定支撐上千臺設(shè)備并發(fā)。
  • 游戲服務(wù)器:網(wǎng)游 / 手游的實時通信層(如走位、攻擊、聊天):

    • 玩家操作指令(如「移動」「釋放技能」)必須有序到達服務(wù)端,否則畫面錯亂;
    • 服務(wù)端實時推送其他玩家狀態(tài),需要全雙工通信;
    • Go 的 TCPConn 結(jié)合 bufio 做消息拆包,性能和并發(fā)都能滿足中小游戲需求。
  • 金融 / 支付系統(tǒng):銀行、支付網(wǎng)關(guān)的私有通信協(xié)議:

    • 轉(zhuǎn)賬、交易指令絕對不能丟包 / 重復(fù)(TCP 可靠傳輸是底線);
    • 長連接減少多次建立連接的開銷,提升交易速度;
    • Go 的 TCP 編程可輕松加解密、簽名驗證,保障數(shù)據(jù)安全。

自定義私有協(xié)議的服務(wù)(替代 HTTP,更輕量 / 靈活)

  • 內(nèi)部運維工具:公司內(nèi)部的服務(wù)器監(jiān)控 / 管理工具,自定義極簡協(xié)議:

    • 客戶端發(fā) status → 服務(wù)端返回 CPU / 內(nèi)存占用;
    • 客戶端發(fā) restart → 服務(wù)端執(zhí)行重啟邏輯;比 HTTP 少了 Header/Cookie 等開銷,通信更高效。
  • 高性能數(shù)據(jù)傳輸:大數(shù)據(jù)平臺的節(jié)點間通信,自定義協(xié)議(如「數(shù)據(jù)類型 + 數(shù)據(jù)長度 + 數(shù)據(jù)內(nèi)容」):

    • 避免 HTTP 的文本解析開銷,直接二進制傳輸;
    • TCP 可靠傳輸保證大數(shù)據(jù)塊完整到達。

高吞吐的大數(shù)據(jù)傳輸(文件 / 視頻 / 日志)

  • 文件傳輸工具:替代 FTP/SFTP 的輕量文件傳輸服務(wù):

    • 客戶端把文件按塊通過 TCPConn.Write 發(fā)送,服務(wù)端 TCPConn.Read 拼接;
    • TCP 保證文件塊有序、不丟,實現(xiàn)完整文件傳輸。
  • 日志實時采集:分布式系統(tǒng)的日志中心,業(yè)務(wù)服務(wù)器(客戶端)通過 TCP 把日志實時發(fā)送到日志服務(wù)端:

    • 日志數(shù)據(jù)不能丟失(否則排查問題無依據(jù));
    • 長連接持續(xù)傳輸,比 HTTP 輪詢更高效。

分布式系統(tǒng) / 微服務(wù)的內(nèi)部通信

  • 微服務(wù)間的 RPC 底層:gRPC 底層基于 HTTP/2,但 HTTP/2 本質(zhì)還是 TCP 長連接;自定義 RPC 框架(如內(nèi)部私有 RPC)直接基于 net.TCP 實現(xiàn),更靈活。
  • 集群節(jié)點心跳 / 同步:分布式緩存(如 Redis 集群)、分布式數(shù)據(jù)庫(如 TiDB)的節(jié)點間,通過 TCP 長連接發(fā)送心跳包(確認節(jié)點在線)、同步數(shù)據(jù)(如分片信息、事務(wù)日志)。

以上就是使用Go語言構(gòu)建一個最小可用的TCP交互程序的詳細內(nèi)容,更多關(guān)于Go構(gòu)建TCP交互程序的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

新巴尔虎右旗| 巴林右旗| 什邡市| 惠水县| 和顺县| 溧阳市| 南陵县| 青冈县| 鸡泽县| 庆城县| 陇南市| 泾源县| 陆丰市| 奉新县| 普兰店市| 富蕴县| 兴海县| 白玉县| 威海市| 衡水市| 华宁县| 宿迁市| 临夏市| 桐乡市| 云南省| 阿拉善盟| 个旧市| 遂川县| 房产| 东方市| 柳江县| 义马市| 洛浦县| 临江市| 尉氏县| 华宁县| 恭城| 台安县| 平和县| 株洲县| 葵青区|