从书CSAPP理解代码片段open_clientfd(char * hostname,char * port)吗?

时间:2019-01-15 09:42:35

标签: c sockets

在阅读《计算机系统:程序员的观点》这本书时,在“网络编程”一章中,我看到了一个函数:

int open_clientfd(char *hostname, char *port) {
    int clientfd;
    struct addrinfo hints, *listp, *p;

    /* Get a list of potential server addresses */
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_socktype = SOCK_STREAM;  /* Open a connection */
    hints.ai_flags = AI_NUMERICSERV;  /* ... using a numeric port arg. */
    hints.ai_flags |= AI_ADDRCONFIG;  /* Recommended for connections */
    Getaddrinfo(hostname, port, &hints, &listp);

    /* Walk the list for one that we can successfully connect to */
    for (p = listp; p; p = p->ai_next) {

        /* Create the socket descriptor */
        if ((clientfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) 
            continue; /* Socket failed, try the next */
        if (connect(clientfd, p->ai_addr, p->ai_addrlen) != -1) 
            break; /* Success */
        Close(clientfd); /* Connect failed, try another */
    } 

    /* Clean up */
    Freeaddrinfo(listp);
    if (!p) /* All connects failed */
        return -1;
    else    /* The last connect succeeded */
        return clientfd;
}

这行Close(clientfd); /* Connect failed, try another */是我不明白的地方,因为如果套接字创建失败,它将继续,如果成功,它将中断for循环,似乎此行将永远无法获得有机会执行吗?

1 个答案:

答案 0 :(得分:3)

socket成功后,您打开了一个套接字。如果connect失败,则套接字仍然存在并且必须关闭。循环的下一个周期将使用列表中的下一个地址,该地址可能需要socket调用使用不同的参数。这就是为什么不重复使用现有套接字的原因。