无效的connect()调用意外成功-为什么?

时间:2018-06-28 11:35:49

标签: c sockets

我希望以下代码*失败,因为尚未为服务器地址设置有效值(已在调试器中验证-整个结构确实初始化为0,从而使地址族为AF_UNSPEC)。

*不完整的说明性片段

static struct sockaddr_in g_server_addr; 

int main(void)
{
    int hdl;

    hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (-1 == hdl)
    {
        printf("Client Socket creation failed.");
        return -1;
    }

    if(-1 == connect(hdl, (struct sockaddr *) &g_server_addr, sizeof(g_server_addr)))
    {
        printf("Connect() on socket failed.");
        return -1;
    }

    return 0;
}

当我用不正确的输入调用时,我需要connect()失败。
(此代码正在Ubuntu机器上进行测试。)

1 个答案:

答案 0 :(得分:4)

从连接手册页:

  

无连接套接字可以通过连接到地址并将sockaddr的sa_family成员设置为AF_UNSPEC(从内核2.2开始在Linux上受支持)来消除关联。

该联机帮助页有些过时,它可以在任何可以完全断开的套接字上使用,例如TCP套接字。

在实践中,尝试解除尚未连接的流套接字上的关联时没有错误。这就是为什么您不会出错的原因。

如果您需要获取错误,请使用无效的族初始化地址族:

static struct sockaddr_in g_server_addr = { -1 };

这将产生错误-1 EAFNOSUPPORT (Address family not supported by protocol)

另请参阅最新Linux内核的net/ipv4/af_inet.c

int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
                      int addr_len, int flags) {
...
if (uaddr->sa_family == AF_UNSPEC) {
        err = sk->sk_prot->disconnect(sk, flags);
        sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
        goto out;
}
...
out:
    return err;