• 深入理解计算机系统(第三版)第十一章重要内容摘要


    11.1客户端-服务器编程模型

     

     

     

    11.2网络

     

     

     

     

    11.3全球IP因特网

     

     

     13.3.1 IP地址

     

     

     

     

    11.3.2因特网域名

     

     

     

    11.3.3 因特网连接

    11.4套接字接口

    11.4.1 套接字地址结构

    11.4.2 socket函数

    11.4.3connect函数

    11.4.4bind函数

     

    11.4.5listen函数

    11.4.6accept函数

    11.4.7主机和服务的转换

    1.getaddrinfo函数

     

     

     

     

     

     

     2.getnameinfo

     

    11.4.8套接字接口的辅助函数

    1.open_clientfd函数

     

    /* $begin open_clientfd */
    int open_clientfd(char *hostname, char *port) {
        int clientfd, rc;
        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 */
        if ((rc = getaddrinfo(hostname, port, &hints, &listp)) != 0) {
            fprintf(stderr, "getaddrinfo failed (%s:%s): %s
    ", hostname, port, gai_strerror(rc));
            return -2;
        }
      
        /* Walk the list for one that we can successfully connect to */
        for (p = listp; p; p = p->ai_next) {
            /* Create a socket descriptor */
            if ((clientfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) 
                continue; /* Socket failed, try the next */
    
            /* Connect to the server */
            if (connect(clientfd, p->ai_addr, p->ai_addrlen) != -1) 
                break; /* Success */
            if (close(clientfd) < 0) { /* Connect failed, try another */  //line:netp:openclientfd:closefd
                fprintf(stderr, "open_clientfd: close failed: %s
    ", strerror(errno));
                return -1;
            } 
        } 
    
        /* Clean up */
        freeaddrinfo(listp);
        if (!p) /* All connects failed */
            return -1;
        else    /* The last connect succeeded */
            return clientfd;
    }
    /* $end open_clientfd */

     2.open_listenfd函数

     

     

    /* $begin open_listenfd */
    int open_listenfd(char *port) 
    {
        struct addrinfo hints, *listp, *p;
        int listenfd, rc, optval=1;
    
        /* Get a list of potential server addresses */
        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_socktype = SOCK_STREAM;             /* Accept connections */
        hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* ... on any IP address */
        hints.ai_flags |= AI_NUMERICSERV;            /* ... using port number */
        if ((rc = getaddrinfo(NULL, port, &hints, &listp)) != 0) {
            fprintf(stderr, "getaddrinfo failed (port %s): %s
    ", port, gai_strerror(rc));
            return -2;
        }
    
        /* Walk the list for one that we can bind to */
        for (p = listp; p; p = p->ai_next) {
            /* Create a socket descriptor */
            if ((listenfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) 
                continue;  /* Socket failed, try the next */
    
            /* Eliminates "Address already in use" error from bind */
            setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,    //line:netp:csapp:setsockopt
                       (const void *)&optval , sizeof(int));
    
            /* Bind the descriptor to the address */
            if (bind(listenfd, p->ai_addr, p->ai_addrlen) == 0)
                break; /* Success */
            if (close(listenfd) < 0) { /* Bind failed, try the next */
                fprintf(stderr, "open_listenfd close failed: %s
    ", strerror(errno));
                return -1;
            }
        }
    
    
        /* Clean up */
        freeaddrinfo(listp);
        if (!p) /* No address worked */
            return -1;
    
        /* Make it a listening socket ready to accept connection requests */
        if (listen(listenfd, LISTENQ) < 0) {
            close(listenfd);
        return -1;
        }
        return listenfd;
    }/* $end open_listenfd */

    11.4.9echo客户端和服务器的示例

    11.5Web服务器

    11.5.1Web基础

     

    11.5.2Web内容

     

     

     

    11.5.3HTTP事务

     1.HTTP请求

     

     2.HTTP响应

     

    11.5.4服务动态内容

    1.客户端如何将程序参数传递给服务器

     

     2.服务器如何将参数传递给子进程

     3.服务器如何将其他信息传递给子进程

     4.子进程将它的输出发送到哪里

     

    11.6综合:TINY Web服务器

  • 相关阅读:
    使用 awk 命令统计文本
    Mysql基础及系统函数(分享)
    存储过程 :字段按逗号拆分并插入到关联表
    Spring Security SavedRequestAwareAuthenticationSuccessHandler类
    自制Springboot Starter
    vue3 input中回车生成标签
    NOMURA Programming Contest 2022(AtCoder Beginner Contest 253)
    Educational Codeforces Round 129 (Rated for Div. 2)
    Panasonic Programming Contest 2022(AtCoder Beginner Contest 251)
    2022 Google Kick Start Round C
  • 原文地址:https://www.cnblogs.com/GodZhuan/p/14295959.html
Copyright © 2020-2023  润新知