我正在尝试使用Golang创建一个TCP服务器和客户端,我可以在其中设置IP报头中的服务类型字段,以便区分不同的流量流的优先级。

客户端和服务器可以通信,但我不知道如何设置ToS字段。

我已经尝试通过这里描述的方法使用ipv4 Golang包:https://godoc.org/golang.org/x/net/ipv4#NewConn

一个简化的服务器示例:

func main () {
ln, err := net.Listen("tcp4", "192.168.0.20:1024")
if err != nil {
    // error handling
}
defer ln.Close()
for {
    c, err := ln.Accept()
    if err != nil {
        // error handling
    }
    go func(c net.Conn) {
        defer c.Close()

        if err := ipv4.NewConn(c).SetTOS(0x28); err != nil {
            fmt.Println("Error: ", err.Error())
        }
    }(c)
}

和相应的客户端(也是简化的)

func main () {

    conn, err := net.Dial("tcp4", "192.168.0.20:1024")
    if err != nil {
        fmt.Println(err)
    }

    for {

            writer := bufio.NewWriter(conn)
            // Create "packet"
            Data := make([]byte, 1200)
            endLine := "\r\n"



            //Set packetLength
            length := strconv.FormatInt(int64(1200), 10)
            copy(Data[0:], length)

            //Set ID
            idString := strconv.FormatInt(int64(1), 10)
            if strings.Contains(idString, "\r") || strings.Contains(idString, "\n") || strings.Contains(idString, "\r\n") {
                fmt.Println("This is gonna result in an error in the id string.")
            }
            idbuf := []byte(idString)
            copy(Data[15:], idbuf)

            //Set timestamp
            timestamp0 := time.Now().UnixNano()
            timestampString := strconv.FormatInt(timestamp0, 10)
            if strings.Contains(timestampString, "\r") || strings.Contains(timestampString, "\n") || strings.Contains(timestampString, "\r\n") {
                fmt.Println("This is gonna result in an error in the timestamp string.")
            }
            buf := []byte(timestampString)
            copy(Data[50:], buf)

            copy(Data[int(1200)-2:], endLine)

            if len(Data) != int(1200) {
                fmt.Println("This is also gonna be an error. Length is: ", len(Data))
            }
            //Send the data and flush the writer
            writer.Write(Data)
            writer.Flush()
        }
        //time.Sleep(1*time.Nanosecond)
    }

我还尝试创建我自己的拨号器,它有一个控制函数,可以传递一个syscall来设置套接字,如下所示:

    dialer := &net.Dialer{
        Timeout:       5 * time.Second,
        Deadline:      time.Time{},
        LocalAddr:     tcpAddr,
        DualStack:     false,
        FallbackDelay: 0,
        KeepAlive:     0,
        Resolver:      nil,
        Control:       highPrio,
    }

    func highPrio(network, address string, c syscall.RawConn) error {
    return c.Control(func(fd uintptr) {
        // set the socket options
        err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, syscall.IP_TOS, 128)
        if err != nil {
            log.Println("setsocketopt: ", err)
        }
    })

我正在使用Wireshark检查流量,并使用Windows 10专业版作为我的操作系统,以确认它不起作用。