如何填写syscall.Sockaddr结构,以便稍后可以在syscall.Bind中使用它?

huangapple go评论70阅读模式
英文:

How do I fill out the syscall.Sockaddr structure so that I can later use it with syscall.Bind?

问题

使用go语言在Windows上,我有一个名为sock的syscall.Handle,我想将其绑定到一个名为"sa"的syscall.Sockaddr结构中指定的地址。

我该如何填写syscall.Sockaddr结构,以便稍后可以将其与syscall.Bind一起使用?

顺便说一下,sock是一个原始套接字。

var sa syscall.Sockaddr // 如何用我的IP地址填写这个结构?

e := syscall.Bind(sock, sa)

if e != nil {
	fmt.Println("bind error", e)
}
英文:

Using go on Windows I have a syscall.Handle called sock that I want to bind to an address specified in a syscall.Sockaddr structure called "sa".

How do I fill out the syscall.Sockaddr structure so that I can later use it with syscall.Bind?

BTW, sock is a raw socket.

var sa syscall.Sockaddr // how to fill out this structure with my ip address???

e := syscall.Bind(sock, sa)

if e != nil {
	fmt.Println("bind error", e)
}

答案1

得分: 7

当你在go语言中对某些事情不确定时,一个好的经验法则是“查看源代码”,特别是在涉及系统调用的地方。我怀疑缺乏文档是半有意的,因为正如之前提到的,这不是推荐的接口 - 最好使用net包来实现可移植的解决方案 如何填写syscall.Sockaddr结构,以便稍后可以在syscall.Bind中使用它?

一旦你进入源代码($GOROOT/src/pkg/syscall/syscall_windows.go),你会注意到Sockaddr根本不是一个结构体:

type Sockaddr interface {
        sockaddr() (ptr uintptr, len int32, err error) // 小写;只有我们可以定义Sockaddrs
}

所以让我们寻找实现这个接口的结构体:

func (sa *SockaddrInet4) sockaddr() (uintptr, int32, error) {
func (sa *SockaddrInet6) sockaddr() (uintptr, int32, error) {
func (sa *SockaddrUnix) sockaddr() (uintptr, int32, error) {

在我查看的版本(1.0.2)中,Inet6和Unix的实现只是存根,但SockaddrInet4已经准备好了:

type SockaddrInet4 struct {
        Port int
        Addr [4]byte
        raw  RawSockaddrInet4
}

只需要填写Port和Addr即可。

英文:

A good rule of thumb when you're unsure of something in go is "check the source", especially where the syscall stuff is concerned. I suspect the lack of documentation is semi-intentional because as previously mentioned, it's not the recommended interface - better to use the net package for a portable solution 如何填写syscall.Sockaddr结构,以便稍后可以在syscall.Bind中使用它?

Once you get to the source ($GOROOT/src/pkg/syscall/syscall_windows.go), you'll notice that Sockaddr isn't a struct at all:

type Sockaddr interface {
        sockaddr() (ptr uintptr, len int32, err error) // lowercase; only we can define Sockaddrs
}

So lets look for structs that implement this interface:

func (sa *SockaddrInet4) sockaddr() (uintptr, int32, error) {
func (sa *SockaddrInet6) sockaddr() (uintptr, int32, error) {
func (sa *SockaddrUnix) sockaddr() (uintptr, int32, error) {

The Inet6 and Unix implementations are just stubs in the version I'm looking at (1.0.2), but SockaddrInet4 is ready to go:

type SockaddrInet4 struct {
        Port int
        Addr [4]byte
        raw  RawSockaddrInet4
}

Just need to fill in Port and Addr.

huangapple
  • 本文由 发表于 2011年11月3日 03:24:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/7986156.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定