使用Go創(chuàng)建一個(gè)TCP服務(wù)器的操作步驟
一、實(shí)戰(zhàn)背景
相比 HTTP 請(qǐng)求響應(yīng),TCP 通信更底層、更靈活,適合用在:
- 游戲服務(wù)器
- 實(shí)時(shí)聊天程序
- 長(zhǎng)連接服務(wù)
- 數(shù)據(jù)同步服務(wù)
本案例將實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 TCP 聊天 服務(wù)器:
- 支持多個(gè)客戶端連接
- 客戶端發(fā)送內(nèi)容,服務(wù)器打印并回應(yīng)
- 演示并發(fā)連接處理
二、實(shí)戰(zhàn)目標(biāo)
構(gòu)建一個(gè)簡(jiǎn)單的 TCP 網(wǎng)絡(luò)程序,包含兩個(gè)組件:
TCP服務(wù)器
- 啟動(dòng)監(jiān)聽(tīng)指定端口
- 接收多個(gè)客戶端連接
- 每條連接獨(dú)立處理,讀取數(shù)據(jù)并回復(fù)
TCP客戶端
- 連接到服務(wù)器
- 從終端輸入消息并發(fā)送
- 接收服務(wù)器返回的響應(yīng)
三、完整代碼實(shí)現(xiàn)
1. TCP服務(wù)器代碼(server.go)
package main
import (
"bufio"
"fmt"
"net"
"strings"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
addr := conn.RemoteAddr().String()
fmt.Println("客戶端連接:", addr)
reader := bufio.NewReader(conn)
for {
data, err := reader.ReadString('\n')
if err != nil {
fmt.Println("客戶端斷開(kāi):", addr)
return
}
msg := strings.TrimSpace(data)
fmt.Printf("收到[%s]: %s\n", addr, msg)
// 回復(fù)消息
response := fmt.Sprintf("服務(wù)端收到: %s\n", msg)
conn.Write([]byte(response))
}
}
func main() {
listener, err := net.Listen("tcp", ":8888")
if err != nil {
fmt.Println("啟動(dòng)失敗:", err)
return
}
defer listener.Close()
fmt.Println("TCP服務(wù)器已啟動(dòng),監(jiān)聽(tīng)端口 8888...")
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("連接失敗:", err)
continue
}
go handleConnection(conn)
}
}
2. TCP客戶端代碼(client.go)
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8888")
if err != nil {
fmt.Println("連接服務(wù)器失敗:", err)
return
}
defer conn.Close()
fmt.Println("已連接到服務(wù)器。請(qǐng)輸入消息,輸入 exit 退出:")
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print(">> ")
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(input)
if input == "exit" {
fmt.Println("斷開(kāi)連接")
return
}
// 發(fā)送消息
conn.Write([]byte(input + "\n"))
// 接收服務(wù)器響應(yīng)
response, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Println("服務(wù)器響應(yīng):", strings.TrimSpace(response))
}
}
四、運(yùn)行方式
啟動(dòng)服務(wù)器
go run server.go
輸出示例:
TCP服務(wù)器已啟動(dòng),監(jiān)聽(tīng)端口 8888...
啟動(dòng)客戶端(多個(gè)終端可同時(shí)運(yùn)行)
go run client.go
輸入消息:
>> hello 服務(wù)器響應(yīng): 服務(wù)端收到: hello
服務(wù)器端輸出:
客戶端連接: 127.0.0.1:53458 收到[127.0.0.1:53458]: hello
五、關(guān)鍵技術(shù)點(diǎn)解析
1. net.Listen("tcp", ":8888")
用于監(jiān)聽(tīng)本地 8888 端口,協(xié)議為 TCP。支持 IPv4、IPv6。
2. listener.Accept()
阻塞方法,等待客戶端連接。每當(dāng)有新連接,就返回一個(gè) net.Conn。
3. 并發(fā)處理連接
使用 go handleConnection(conn),每個(gè)客戶端獨(dú)立處理,避免阻塞。
4. bufio.NewReader(conn).ReadString('\n')
按行讀取客戶端發(fā)送內(nèi)容。注意客戶端必須發(fā)送換行(\n)結(jié)束,否則會(huì)阻塞。
5. 客戶端 net.Dial
客戶端使用 net.Dial("tcp", addr) 建立連接。注意服務(wù)端地址和端口應(yīng)正確。
六、可擴(kuò)展方向
| 方向 | 實(shí)現(xiàn)建議 |
|---|---|
| 廣播機(jī)制 | 使用 map[conn]bool 存儲(chǔ)連接,廣播消息 |
| 客戶端昵稱 | 每個(gè)連接輸入昵稱,并用于標(biāo)識(shí)消息來(lái)源 |
| 心跳檢測(cè) | 定期向客戶端發(fā)送 ping,判斷是否掉線 |
| JSON 協(xié)議 | 使用結(jié)構(gòu)化數(shù)據(jù)通訊 |
| TLS 加密通信 | 使用 crypto/tls 加密 TCP 通道 |
| 多線程聊天室 | 支持多房間并發(fā)聊天 |
七、小結(jié)
通過(guò)本案例你掌握了:
- 如何編寫基本的 TCP 服務(wù)端和客戶端
- 使用 Goroutine 實(shí)現(xiàn)并發(fā)連接處理
- 使用
bufio.Reader/Writer實(shí)現(xiàn)按行讀寫 - 終端交互式發(fā)送/接收消息
這是構(gòu)建分布式系統(tǒng)、即時(shí)通訊、遠(yuǎn)程控制服務(wù)的基礎(chǔ)能力。
到此這篇關(guān)于使用Go創(chuàng)建一個(gè)TCP服務(wù)器的操作步驟的文章就介紹到這了,更多相關(guān)Go創(chuàng)建TCP服務(wù)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang中interface轉(zhuǎn)string輸出打印方法
這篇文章主要給大家介紹了關(guān)于Golang中interface轉(zhuǎn)string輸出打印的相關(guān)資料,在go語(yǔ)言中interface轉(zhuǎn)string可以直接使用fmt提供的fmt函數(shù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02
Go?http請(qǐng)求排隊(duì)處理實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了Go?http請(qǐng)求排隊(duì)處理實(shí)戰(zhàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Go語(yǔ)言通過(guò)反射實(shí)現(xiàn)獲取各種類型變量的值
反射是程序在運(yùn)行期間獲取變量的類型和值、或者執(zhí)行變量的方法的能力,這篇文章主要為大家講講Go語(yǔ)言通過(guò)反射獲取各種類型變量值的方法,需要的可以參考下2023-07-07
Golang時(shí)間及時(shí)間戳的獲取轉(zhuǎn)換超全面詳細(xì)講解
說(shuō)實(shí)話,golang的時(shí)間轉(zhuǎn)化還是很麻煩的,最起碼比php麻煩很多,下面這篇文章主要給大家介紹了關(guān)于golang時(shí)間/時(shí)間戳的獲取與轉(zhuǎn)換的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
Go語(yǔ)言range關(guān)鍵字循環(huán)時(shí)的坑
今天小編就為大家分享一篇關(guān)于Go語(yǔ)言range關(guān)鍵字循環(huán)時(shí)的坑,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
Go gorilla securecookie庫(kù)的安裝使用詳解
這篇文章主要介紹了Go gorilla securecookie庫(kù)的安裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

