Linux syscall.Sockaddr类型断言

Linux syscall.Sockaddr类型断言,linux,sockets,go,type-assertion,Linux,Sockets,Go,Type Assertion,我正在打开Linux数据包套接字并尝试将收到的数据包读入结构: type msg struct { n, oobn, flags int p, oob []byte from syscall.Sockaddr } socket, err := syscall.Socket(AF_PACKET, SOCK_RAW, ETH_P_ALL) pkt := new(msg) pkt.p = make([]byte, 1500) pkt.oob = make([]byte, 1

我正在打开Linux数据包套接字并尝试将收到的数据包读入结构:

type msg struct {
    n, oobn, flags int
    p, oob []byte
    from syscall.Sockaddr
}

socket, err := syscall.Socket(AF_PACKET, SOCK_RAW, ETH_P_ALL)

pkt := new(msg)
pkt.p = make([]byte, 1500)
pkt.oob = make([]byte, 1500)

pkt.n, pkt.oobn, pkt.flags, pkt.from, _ = syscall.Recvmsg(socket, pkt.p, pkt.oob, 0)
根据文档()
Recvmsg()
将msghdr作为一个
syscall.Sockaddr
返回,并且我上面概述的代码段可以工作

打印出
pkt.from
struct成员,我可以看到
Sockaddr
界面中的值:

fmt.Printf("%+v\n", pkt.from)

>>> &{Protocol:8 Ifindex:3 Hatype:1 Pkttype:0 Halen:6 Addr:[0 0 36 205 126 213 0 0] raw:{Family:0 Protocol:0 Ifindex:0 Hatype:0 Pkttype:0 Halen:0 Addr:[0 0 0 0 0 0 0 0]}}
但是,如果我尝试访问它们,我会得到一个错误:

fmt.Println(pkt.from.Ifindex)

>>> pkt.from.Ifindex undefined (type syscall.Sockaddr has no field or method Ifindex)
通过
reflect.TypeOf(pkt.from)
我发现它的类型是
*syscall.SockaddrLinklayer
。当
Recvmsg
尝试执行赋值时,尝试将我的
msg
结构成员更改为该类型失败,因为它不是类型
syscall.Sockaddr

我能够使用类型断言:

bar := pkt.from.(*syscall.SockaddrLinklayer)
fmt.Println(bar.Ifindex)

>>> 2

我是新来的;这是我的第一个静态类型语言,所以我不明白
Recvmsg
func如何需要
syscall.Sockaddr
但是
*syscall.SockaddrLinklayer
返回一个
?我显然遗漏了一些非常基本的东西。另外,使用类型断言是正确的方法吗?感觉不太对劲。。。但我真的没有资格做出这样的判断

Sockaddr是一个接口,因此,
Recvmsg
可以返回实现该接口的不同类型

有关接口的更多详细信息,请查看

您应该检查断言是否有效,以避免出现运行时错误,例如:

bar, ok := pkt.from.(*syscall.SockaddrLinklayer) 
if !ok {
    //log error and break out of the loop
}
stuffWith(bar)

Sockaddr是一个接口,因此
Recvmsg
可以返回实现该接口的不同类型

有关接口的更多详细信息,请查看

您应该检查断言是否有效,以避免出现运行时错误,例如:

bar, ok := pkt.from.(*syscall.SockaddrLinklayer) 
if !ok {
    //log error and break out of the loop
}
stuffWith(bar)

Sockaddr是一个接口,因此
Recvmsg
可以返回实现该接口的不同类型

有关接口的更多详细信息,请查看

您应该检查断言是否有效,以避免出现运行时错误,例如:

bar, ok := pkt.from.(*syscall.SockaddrLinklayer) 
if !ok {
    //log error and break out of the loop
}
stuffWith(bar)

Sockaddr是一个接口,因此
Recvmsg
可以返回实现该接口的不同类型

有关接口的更多详细信息,请查看

您应该检查断言是否有效,以避免出现运行时错误,例如:

bar, ok := pkt.from.(*syscall.SockaddrLinklayer) 
if !ok {
    //log error and break out of the loop
}
stuffWith(bar)

好的,这是有道理的。使用类型断言是读取此数据的“正确”方式吗?@tMC是的,但您必须确保它是有效的,我添加了一个小示例。好的-这很有意义。使用类型断言是读取此数据的“正确”方式吗?@tMC是的,但您必须确保它是有效的,我添加了一个小示例。好的-这很有意义。使用类型断言是读取此数据的“正确”方式吗?@tMC是的,但您必须确保它是有效的,我添加了一个小示例。好的-这很有意义。使用类型断言是读取此数据的“正确”方法吗?@tMC是的,但您必须确保它是有效的,我添加了一个小示例。