2024-01-08|閱讀時間 ‧ 約 25 分鐘

[Go][Socket]聊天室(Client)

package main

import (
"bufio"
"fmt"
"net"
"os"
"time"
)

func main() {
//指定協定
tcpAddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:8086")
if err != nil {
Log(os.Stderr, "Fatal error:", err.Error())
os.Exit(1)
}

//建立連線
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
Log("Fatal error:", err.Error())
os.Exit(1)
}
Log(conn.RemoteAddr().String(), "連線成功!")

//發送心跳封包
Sender(conn)
Log("end")
}

func Sender(conn *net.TCPConn) {
defer conn.Close()
sc := bufio.NewReader(os.Stdin)
go func() {
//建立計時器​,用於定時發送心跳封包
t := time.NewTicker(time.Second)
defer t.Stop()
for {
<-t.C
_, err := conn.Write([]byte("1"))
if err != nil {
fmt.Println(err.Error())
return
}
}
}()

name := ""
fmt.Println("請輸入暱稱")
fmt.Fscan(sc, &name)
msg := ""
buffer := make([]byte, 1024)

//建立計時器,每次發送訊息就刷新時間
_t := time.NewTimer(time.Second * 5)
defer _t.Stop()

go func() {
<-_t.C
fmt.Println("伺服器故障,斷開鏈接")
return
}()

for {
go func() {
for {
n, err := conn.Read(buffer)
if err != nil {
return
}

//收到訊息就刷新計時器,如果time.Second*5時間到了,那麼就會<-_t.C就不會阻塞,程式碼會往下走,return結束
_t.Reset(time.Second * 5)

//心跳封包訊息定義為字串"1",不需要列印出來
if string(buffer[0:1]) != "1" {
fmt.Println(string(buffer[0:n]))
}
}
}()
fmt.Fscan(sc, &msg)
i := time.Now().Format("2022-01-02 15:04:05")
conn.Write([]byte(fmt.Sprintf("%s\n\t%s: %s", i, name, msg))) //發送訊息
}
}

func Log(v ...interface{}) {
fmt.Println(v...)
return
}





分享至
成為作者繼續創作的動力吧!
此專題是與後端程式設計相關的內容,包含:PHP、SQL...。
從 Google News 追蹤更多 vocus 的最新精選內容從 Google News 追蹤更多 vocus 的最新精選內容

發表回應

成為會員 後即可發表留言
© 2024 vocus All rights reserved.