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

使用Go語言構建一個最小可用的TCP交互程序

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

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

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

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

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

交互效果

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

實例代碼

// server.go
package main

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

// 啟動TCP服務端
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 {
			// 普通回聲響應
			response = fmt.Sprintf("【服務端回聲】%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 → 響應:%s", clientAddr, msg, strings.TrimSpace(response))
	}
}

func main() {
	fmt.Println("啟動服務...")
	startTCPServer()
}
// client.go
package main
import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)
// 啟動TCP客戶端
func startTCPClient() {
	// 解析服務端地址
	tcpAddr, err := net.ResolveTCPAddr("tcp", ":8888")
	if err != nil {
		fmt.Printf("解析服務端地址失敗:%v\n", err)
		return
	}
	// 連接服務端
	conn, err := net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		fmt.Printf("連接服務端失?。?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("已斷開與服務端的連接")
			return
		}
		// 向服務端發(fā)送數(shù)據(jù)
		_, err = conn.Write([]byte(input + "\n"))
		if err != nil {
			fmt.Printf("發(fā)送數(shù)據(jù)失?。?v\n", err)
			return
		}
		// 讀取服務端響應
		response, err := bufio.NewReader(conn).ReadString('\n')
		if err != nil {
			fmt.Printf("讀取服務端響應失?。?v\n", err)
			return
		}
		fmt.Printf("服務端回復:%s", strings.TrimSpace(response))
	}
}
func main() {
	fmt.Println("啟動客戶端...")
	startTCPClient()
}

基礎概念

Net 包介紹

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

TCP 基本概念

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

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

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

握手 / 揮手機制

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

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

1.ResolveTCPAddr

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

參數(shù):

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

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

2.ListenTCP

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

步驟:

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

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

3.AcceptTCP

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

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

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

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

1.DialTCP

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

參數(shù):

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

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

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

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

3.長連接維護

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

Error 檢測:

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

使用場景

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

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

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

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

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

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

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

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

    • 客戶端發(fā) status → 服務端返回 CPU / 內(nèi)存占用;
    • 客戶端發(fā) restart → 服務端執(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 的輕量文件傳輸服務:

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

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

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

  • 微服務間的 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ù)(如分片信息、事務日志)。

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

相關文章

最新評論

新郑市| 和平区| 丰顺县| 宁武县| 桦川县| 辽阳县| 白银市| 石城县| 陈巴尔虎旗| 叙永县| 永春县| 安平县| 玉门市| 监利县| 客服| 温宿县| 清新县| 长兴县| 鲜城| 昌邑市| 宿迁市| 赞皇县| 冷水江市| 邵阳市| 清涧县| 开鲁县| 德清县| 清流县| 武清区| 射洪县| 开远市| 深水埗区| 古丈县| 芒康县| 瑞丽市| 广平县| 大同市| 仪陇县| 涪陵区| 龙口市| 文成县|