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)
}
}

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()
}
- 2 回答
- 0 關注
- 134 瀏覽
添加回答
舉報