Go 捕捉;绑定:地址已在使用中“;在戈兰
我想捕获golang中的“绑定:地址已在使用”错误Go 捕捉;绑定:地址已在使用中“;在戈兰,go,error-handling,udp,Go,Error Handling,Udp,我想捕获golang中的“绑定:地址已在使用”错误 conn, err := net.ListenUDP("udp", addr) if err != nil { if CATCH_BIND_ERROR(err) { // Do something if 'addr' is already in use } else { panic(err) } } 有没有办法实现CATCH\u BIND\u ERROR函数?简单的方法就是检查错误文
conn, err := net.ListenUDP("udp", addr)
if err != nil {
if CATCH_BIND_ERROR(err) {
// Do something if 'addr' is already in use
} else {
panic(err)
}
}
有没有办法实现CATCH\u BIND\u ERROR函数?简单的方法就是检查错误文本:
conn, err := net.ListenUDP("udp", addr)
if err != nil && err.Error() == "bind: address already in use" {
// Failed to bind, do something
}
if err != nil {
// Some other error
panic(err)
}
对于这样一个简单的情况,这可能就足够了。然而,这种方法有些脆弱:
conn, err := net.ListenUDP("udp", addr)
if opErr, ok := err.(*net.OpError); ok {
if opErr.Op == "listen" && strings.Contains(opErr.Error.Error(), "address already in use") {
// Failed to bind, do something
}
}
if err != nil {
// Some other error, panic
panic(err)
}
在这种情况下,我们仍然依赖于文本检查,因此未来的库更改仍有可能破坏测试。但是,通过检查
net.OpError
类型,我们确实降低了第二个风险,即可能会出现其他一些具有相同文本的错误。在Windows上,错误消息是“通常只允许使用每个套接字地址(协议/网络地址/端口)。
”
此外,在本地化的情况下,消息将发生更改
以下是捕获“地址已在使用”错误的可能解决方案:
要使用此功能,请执行以下操作:
conn, err := net.ListenUDP("udp", addr)
if err != nil {
if isErrorAddressAlreadyInUse(err) {
// Do something if 'addr' is already in use
} else {
panic(err)
}
}
要使用Go 1.13更新Star Brilliant的最佳答案:
func-isErrorAddressAlreadyInUse(err-error)bool{
变量eOsSyscall*os.SyscallError
if!errors.As(err,&eOsSyscall){
返回错误
}
var Errno syscall.Errno//不需要“*”(ptr),因为它已经是一个ptr(uintpttr)
if!errors.As(eOsSyscall,&errno){
返回错误
}
如果errno==syscall.EADDRINUSE{
返回真值
}
常数WSAEADDRINUSE=10048
如果runtime.GOOS==“windows”&&errno==WSAEADDRINUSE{
返回真值
}
返回错误
}
检查字符串是一个危险的想法。查看并验证这样的内容是否有助于您构造正确的错误类型,以对照您在Windows上的调用返回的结果进行检查,错误消息是“每个套接字地址(协议/网络地址/端口)通常只允许使用一次”。我请您检查我的支持Windows的解决方案。:-)@StarBrilliant:这是一个很好的例子,说明为什么检查错误消息的文本是一种不好的做法:)errors.As()
应该可以与syscall.Errno一起工作;您只需要传入指向syscall.Errno
的指针,而不是指向指针的指针,因为syscall.Errno
是实现error
的类型,而不是*syscall.Errno
<代码>变量Errno syscall.Errno<代码>如果!errors.As(eOsSyscall.Err,&errErrno){return false}谢谢@thepaul,我已经更新了我的代码片段。
conn, err := net.ListenUDP("udp", addr)
if err != nil {
if isErrorAddressAlreadyInUse(err) {
// Do something if 'addr' is already in use
} else {
panic(err)
}
}