[英]syscall.Sockaddr Type Assertion
I am opening a Linux packet socket and trying to read received packets into a struct: 我正在打开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)
Per the documentation ( http://golang.org/pkg/syscall/#Recvmsg ) Recvmsg()
returns the msghdr as a syscall.Sockaddr
and the code pieces I've outlined above works. 根据文档( http://golang.org/pkg/syscall/#Recvmsg ),
Recvmsg()
将msghdr作为syscall.Sockaddr
和上面概述的代码段工作。
Printing out the pkt.from
struct member, I can see the values in the Sockaddr
interface: 打印出
pkt.from
结构成员,我可以看到在值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]}}
However, if I try to access them, I get an error: 但是,如果尝试访问它们,则会收到错误消息:
fmt.Println(pkt.from.Ifindex)
>>> pkt.from.Ifindex undefined (type syscall.Sockaddr has no field or method Ifindex)
Via reflect.TypeOf(pkt.from)
I found it was of type *syscall.SockaddrLinklayer
. 通过
reflect.TypeOf(pkt.from)
我发现它的类型为*syscall.SockaddrLinklayer
。 Trying to change my msg
struct member to that type fails when Recvmsg
tries to do the assignment since it not of type syscall.Sockaddr
. 当
Recvmsg
尝试执行分配时,尝试将我的msg
struct成员更改为该类型失败,因为它不是syscall.Sockaddr
类型。
I was able to use a type assertion: 我能够使用类型断言:
bar := pkt.from.(*syscall.SockaddrLinklayer)
fmt.Println(bar.Ifindex)
>>> 2
I'm very new to Go; 我是Go的新手。 it is my first statically typed language so I don't understand how the
Recvmsg
func is requiring a syscall.Sockaddr
but returning a *syscall.SockaddrLinklayer
? 这是我的第一种静态类型语言,所以我不明白
Recvmsg
函数是如何要求 syscall.Sockaddr
但是返回了*syscall.SockaddrLinklayer
呢? I'm clearly missing something very fundamental. 我显然缺少了一些非常基本的东西。 Also, is using the type assertion the correct way to do this?
另外,使用类型断言是执行此操作的正确方法吗? It doesn't really feel right... but I'm not really qualified to make such judgments!
感觉真的不对……但是我没有资格做出这样的判断!
Sockaddr is an interface, so Recvmsg
can return different types that fulfill that interface. Sockaddr是一个接口,因此
Recvmsg
可以返回满足该接口的不同类型。
For more details about interfaces check Effective Go . 有关接口的更多详细信息,请查看Effective Go 。
You should check if the assertion is valid or not so you wouldn't end up with a runtime error, for example: 您应该检查断言是否有效,这样就不会导致运行时错误,例如:
bar, ok := pkt.from.(*syscall.SockaddrLinklayer)
if !ok {
//log error and break out of the loop
}
stuffWith(bar)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.