Go 的 netFD.connect Getpeername 检查

问题描述 投票:0回答:1

投反对票的人请注意:我希望您能为投反对票的人提供一些推理。我问这个问题不是出于好奇,而是因为我在测试中遇到了等待问题。

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

go sockets network-programming tcp polling
1个回答
0
投票

实际上

Getpeername
在远程套接字关闭后不会返回错误。

这样我们就不会陷入无休止的等待。

© www.soinside.com 2019 - 2024. All rights reserved.