多进程监听一个端口

2021-08-23  本文已影响0人  onmeiei

SO_REUSEADDR,SO_REUSEPORT,这个给忘记了,搜了好久才找到,做个笔记。

示例程序

package main

import (
    "context"
    "net"
    "net/http"
    "os"
    "syscall"

    "github.com/sirupsen/logrus"
    "golang.org/x/sys/unix"
)

type TestHandler struct {
    RESP []byte
}

func (handler *TestHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
    resp.WriteHeader(200)
    resp.Write(handler.RESP)
}

func Control(network, address string, c syscall.RawConn) error {
    var err error
    c.Control(func(fd uintptr) {
        err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1)
        if err != nil {
            logrus.Error("Failed to set SO_REUSEADDR. ", err)
            return
        }

        err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
        if err != nil {
            logrus.Error("Failed to set SO_REUSEPORT. ", err)
            return
        }
    })
    return err
}

func main() {
    for i, arg := range os.Args {
        logrus.Info("Arg ", i, " is ", arg)
    }

    lc := &net.ListenConfig{
        Control: Control,
    }

    ln, err := lc.Listen(context.Background(), "tcp4", os.Args[1])
    if err != nil {
        logrus.Panic("Failed to listen. ", err)
    }

    err = http.Serve(ln, &TestHandler{
        RESP: []byte(os.Args[2]),
    })
    if err != nil {
        logrus.Panic("Failed to listen. ", err)
    }
}
上一篇下一篇

猜你喜欢

热点阅读