亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果連接沒有每秒收到響應,我該如何使 TCP 連接超時?

如果連接沒有每秒收到響應,我該如何使 TCP 連接超時?

Go
繁花如伊 2022-12-05 16:49:37
我正在嘗試創建一個 TCP 服務器,如果客戶端在每秒的范圍內沒有響應,它將超時。我試過了:func main() {    listener, err := net.Listen("tcp", "localhost:8000")    if err != nil {        log.Fatal(err)    }    for {        conn, err := listener.Accept()        conn.SetDeadline(time.Now().Add(timeout))        if err != nil {            log.Print(err)        }        go handleConn(conn)    }}超時是一秒鐘但立即斷開連接,甚至不等待回復。
查看完整描述

2 回答

?
茅侃侃

TA貢獻1842條經驗 獲得超22個贊

您可以通過在偵聽器上設置套接字選項來實現您想要的。根據您的需要調整值


請注意,這是它自己的 KeepAlive,不依賴于應用程序的傳入/傳出數據


func enableTCPKeepAlive(listener *net.TCPListener) error {

    rawConn, err := listener.SyscallConn()

    if err != nil {

        return err

    }

    cfg := config.TLSServerConfig()

    rawConn.Control(

        func(fdPtr uintptr) {

            // got socket file descriptor. Setting parameters.

            fd := int(fdPtr)

            //Idle time before sending probe.

            err = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, cfg.TCPKAIdleTime)

            if err != nil {

                return err

            }

            //Number of probes.

            err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPCNT, cfg.TCPKANumProbes)

            if err != nil {

                return err

            }

            //Wait time after an unsuccessful probe.

            err = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, cfg.TCPKAInterval)

            if err != nil {

                return err

            }

            // go syscall doesn't have the constant 0x12 (18) for TCP_USER_TIMEOUT.

            // 0x12 value referenced from linux kernel source code header:

            // include/uapi/linux/tcp.h

            err = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, 0x12, cfg.TCPKAUserTimeout)

            if err != nil {

                return err

            }

        })

    return nil

}

可用的選項比我上面提到的要多。在 for 循環之前在您的偵聽器上調用此函數。


func main() {

    listener, err := net.Listen("tcp", "localhost:8000")

    if err != nil {

        log.Fatal(err)

    }

    err = enableTCPKeepAlive(listener)

    if err != nil {

        log.Fatal(err)

    }

    for {

        conn, err := listener.Accept()

        conn.SetDeadline(time.Now().Add(timeout))

        if err != nil {

            log.Print(err)

        }

        go handleConn(conn)

    }


}


查看完整回答
反對 回復 2022-12-05
?
12345678_0001

TA貢獻1802條經驗 獲得超5個贊

問題幾乎總是出在未在此處發布的代碼中。該功能顯然很有魅力:


package main


import (

    "crypto/rand"

    "log"

    "net"

    "time"

)


func main() {

    listener, err := net.Listen("tcp", "localhost:8000")

    if err != nil {

        log.Fatal(err)

    }

    go func() {

        for {

            conn, err := listener.Accept()

            if err != nil {

                log.Print(err)

                return

            }

            go func(c net.Conn) {

                defer c.Close()


                conn.SetDeadline(time.Now().Add(2 * time.Second))

                if err != nil {

                    log.Print(err)

                    return

                }

                buf := make([]byte, 1<<19) // 512 KB

                for {

                    _, err := conn.Read(buf)

                    if err != nil {

                        log.Print(err)

                        break

                    }

                }

            }(conn)

        }

    }()


payload := make([]byte, 1<<20)

_, err = rand.Read(payload) // generate a random payload

if err != nil {

    log.Print(err)

}


conn, err := net.Dial("tcp", listener.Addr().String())

if err != nil {

    log.Fatal(err)

}

log.Println("Connected to server.")


time.Sleep(5 * time.Second)


_, err = conn.Write(payload)

if err != nil {

    log.Print(err)

}


listener.Close()

}


查看完整回答
反對 回復 2022-12-05
  • 2 回答
  • 0 關注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號