我如何从os.Error中获取os.Errno?还有其他使用os.Timeout的方法吗?

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

How can I get os.Errno from os.Error? Other ways to use os.Timeout?

问题

The net.Conn interface provides the SetTimeout methods and I am supposed to check the returned error with os.Timeout. However I see no way of calling os.Timeout on the returned os.Error.

(The os.Error I've got is read unix @: Resource temporarily unavailable which seem to consists of two parts: description of the function which timed out and the strerror description of the EAGAIN. I've tried err == os.EAGAIN and it doesn't work, probably because of the extra information in os.Error).

英文:

The net.Conn interface provides the SetTimeout methods and I am supposed to check the returned error with os.Timeout. However I see no way of calling os.Timeout on the returned os.Error.

(The os.Error I've got is read unix @: Resource temporarily unavailable which seem to consists of two parts: description of the function which timed out and the strerror description of the EAGAIN. I've tried err == os.EAGAIN and it doesn't work, probably because of the extra information in os.Error).

答案1

得分: 1

"An I/O Package"部分的Go教程中有以下代码片段:

func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) {
  r, e := syscall.Open(name, mode, perm)
  if e != 0 {
    err = os.Errno(e)
  }
  return newFile(r, name), err
}

syscall.Open()的签名如下:

func Open(path string, mode int, perm uint32) (fd int, errno int)

所以我认为可以安全地假设os.Error仍然只是整数错误代码,只是添加了一些额外的内容,你检查它的方法是正确的。

为了调查为什么err == os.EAGAIN对你不起作用,我会将错误打印为int类型的值,然后在你的平台的errno.h文件中搜索打印的值。

英文:

The "An I/O Package" section of the Go tutorial has this snippet:

func OpenFile(name string, mode int, perm uint32) (file *File, err os.Error) {
  r, e := syscall.Open(name, mode, perm)
  if e != 0 {
    err = os.Errno(e)
  }
  return newFile(r, name), err
}

syscall.Open() has this signature:

func Open(path string, mode int, perm uint32) (fd int, errno int)

So I think it's safe to assume os.Error is still just that integer error code, just with the added fluff and your approach to check it is correct.

To investigate why err == os.EAGAIN did not work for you, I'd print the error as a value of type int and then grepped your platform's errno.h file for the value printed.

答案2

得分: 0

你需要进行类型断言。假设kon是net.Conn类型,你将读取到缓冲区buf。然后:

if numread, err := kon.Read(buf); err != nil {
    if val, ok := err.(os.Errno); ok {
        if val.Timeout() {
            println("连接到:", kon.RemoteAddr().String(), "超时。")
        }
    }
}

当然,这只是一个简要的想法。在实践中,你可能希望做一些更优雅(更复杂)的事情,并使用类型切换同时考虑更多情况。

英文:

You need to do a type assertion. Let's say kon is type net.Conn and you read into buffer buf. Then:

if numread, err := kon.Read(buf); err != nil {
    if val, ok := err.(os.Errno); ok {
        if val.Timeout() {
            println("Connection to:", kon.RemoteAddr().String(), "timed out.")
        }
    }
}

That's of course only a gist of the idea. In practice you probably want to do something more elegant (aka more RL complexleete) and consider more cases at once with Type switches.

huangapple
  • 本文由 发表于 2011年10月29日 21:51:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/7939300.html
匿名

发表评论

匿名网友

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

确定