投反对票的人请注意:我希望您能为投反对票的人提供一些推理。我问这个问题不是出于好奇,而是因为我在测试中遇到了等待问题。
Go 运行时
net
包中的 netFD.connect 方法摘录如下:
for {
// Performing multiple connect system calls on a
// non-blocking socket under Unix variants does not
// necessarily result in earlier errors being
// returned. Instead, once runtime-integrated network
// poller tells us that the socket is ready, get the
// SO_ERROR socket option to see if the connection
// succeeded or failed. See issue 7474 for further
// details.
if err := fd.pfd.WaitWrite(); err != nil {
select {
case <-ctxDone:
return nil, mapErr(ctx.Err())
default:
}
return nil, err
}
nerr, err := getsockoptIntFunc(fd.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
if err != nil {
return nil, os.NewSyscallError("getsockopt", err)
}
switch err := syscall.Errno(nerr); err {
case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
case syscall.EISCONN:
return nil, nil
case syscall.Errno(0):
// The runtime poller can wake us up spuriously;
// see issues 14548 and 19289. Check that we are
// really connected; if not, wait again.
if rsa, err := syscall.Getpeername(fd.pfd.Sysfd); err == nil {
return rsa, nil
}
default:
return nil, os.NewSyscallError("connect", err)
}
runtime.KeepAlive(fd)
}
在TCP情况下,关于检查我们是否真的与
Getpeername
连接,不是吗?
由于套接字的实际可写性,我们可能得到 SO_ERROR
为零,
但就在调用 Getpeername
之前要接受并关闭远程套接字?
在这种情况下,Getpeername
将返回错误,我们将永远WaitWrite
?
实际上
Getpeername
在远程套接字关闭后不会返回错误。
这样我们就不会陷入无休止的等待。