Socket服務器是網絡服務中常用的服務器。使用go語言實現這個業務場景是很容易的。
這樣的網絡通訊,需要一個服務端和至少一個客戶端。
我們計劃構建一個這樣的通訊工程。服務端啟動后等待客戶端的訪問。客戶端發送一段信息給服務端。服務端接收到信息后,再回饋給客戶端一段信息。
首先要建立服務端。服務端最先要做的事情就是"建立Socket端口監聽"。
netListen, err := net.Listen("tcp", "localhost:1024")
上面的代碼,表名監聽的是本機端口1024,而使用的通訊協議是TCP。
當監聽結束,模塊任務完成后,最后要close這個netListen。
defer netListen.Close()
使用日志功能,讓服務端窗口能看到服務端已經運行了。
Log("Waiting for clients ...")
之后使用一個for循環,無盡的等待那些不知何時來訪問的客戶端信息。
for循環體內,要監聽netListen的信息接收情況:
conn, err := netListen.Accept()
當有來自客戶端的訪問時,接受訪問。并在服務端的日志記錄已經有客戶端連接成功了。
Log(conn.RemoteAddr().String(), "tcp connect success")
conn.RemoteAddr().String()表示的就是遠程客戶端。
然后,我們開啟一個goroutine處理連接任務。
go handleConnection(conn)
處理過程就是接收客戶端信息和反饋給客戶端信息。
n, err := conn.Read(buffer)
conn.Write([]byte(strTemp))
服務端代碼示例
package main
import (
"net"
"fmt"
"os"
"log"
"time"
)
func main() {
//建立socket端口監聽
netListen, err := net.Listen("tcp", "localhost:1024")
CheckError(err)
defer netListen.Close()
Log("Waiting for clients ...")
//等待客戶端訪問
for{
conn, err := netListen.Accept() //監聽接收
if err != nil{
continue //如果發生錯誤,繼續下一個循環。
}
Log(conn.RemoteAddr().String(), "tcp connect success") //tcp連接成功
go handleConnection(conn)
}
}
//處理連接
func handleConnection(conn net.Conn) {
buffer := make([]byte, 2048) //建立一個slice
for{
n, err := conn.Read(buffer) //讀取客戶端傳來的內容
if err != nil{
Log(conn.RemoteAddr().String(), "connection error: ", err)
return //當遠程客戶端連接發生錯誤(斷開)后,終止此協程。
}
Log(conn.RemoteAddr().String(), "receive data string:\n", string(buffer[:n]))
//返回給客戶端的信息
strTemp := "CofoxServer got msg \""+string(buffer[:n])+"\" at "+time.Now().String()
conn.Write([]byte(strTemp))
}
}
//日志處理
func Log(v ...interface{}) {
log.Println(v...)
}
//錯誤處理
func CheckError(err error) {
if err != nil{
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
}
}
客戶端的業務邏輯是,發送信息給服務端,然后接收服務端的反饋。
conn, err := net.DialTCP("tcp", nil, tcpAddr)
用TCP協議撥號(Dial)到服務端。如果沒有發生錯誤,就說明撥通了。于是在客戶端日志記錄連接成功
fmt.Println("connection success")
然后在這個已經通暢的連接里,進行發送和接收信息的任務。conn.Write([]byte(words))是發送信息;conn.Read(buffer)是接收信息。如果接收發生錯誤,就記錄錯誤:
Log(conn.RemoteAddr().String(), "waiting server back msg error: ", err)
并且中斷進程。
如果沒有發生錯誤,酒吧接收到的信息在日志中記錄。
Log(conn.RemoteAddr().String(), "receive server back msg: ", string(buffer[:n]))
客戶端代碼示例
package main
import (
"net"
"fmt"
"log"
"os"
)
//發送信息
func sender(conn net.Conn) {
words := "Hello Server!"
conn.Write([]byte(words))
fmt.Println("send over")
//接收服務端反饋
buffer := make([]byte, 2048)
n, err := conn.Read(buffer)
if err != nil {
Log(conn.RemoteAddr().String(), "waiting server back msg error: ", err)
return
}
Log(conn.RemoteAddr().String(), "receive server back msg: ", string(buffer[:n]))
}
//日志
func Log(v ...interface{}) {
log.Println(v...)
}
func main() {
server := "127.0.0.1:1024"
tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
fmt.Println("connection success")
sender(conn)
}
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- golang 實現tcp server端和client端,并計算RTT時間操作
- 使用Go基于WebSocket構建千萬級視頻直播彈幕系統的代碼詳解
- golang websocket 服務端的實現
- golang socket斷點續傳大文件的實現方法
- golang基于websocket實現的簡易聊天室程序
- golang網絡socket粘包問題的解決方法