zoukankan      html  css  js  c++  java
  • 第11章代码详解

    《深入理解计算机系统》第11章网络编程

    11.4.7主机和服务的转换

    include "csapp.h"

    int main(int argc, char **argv)
    {
    struct addrinfo p,listp,hints;
    char buf[MAXLINE];
    int rc,flags;

    if (argc != 2) {
    fprintf(stderr, "usage: %s <domain name or dotted-decimal>
    ", argv[0]);
    exit(0);
    }
    
    memset(&hints,0,sizeof(struct addrinfo));
    hints.ai_family=AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    if((rc = getaddrinfo(argv[1],NULL,&hints,&listp)) != 0) {
        fprintf(stderr,"getaddrinfo error : %s
    ",gai_strerroe(rc));
        exit(1);
    }
    
    exit(0);
    

    }
    c语言给main函数传参。
    有两种传参格式:

    int main(int argc, char** argv)

    int main(int argc, char* argv[])

    argc 是指命令行输入参数的个数,argv是一个字符数组(或者二重指针)用来存放多个字符串,每个字符串就是一个参数。

    注意在命令行下运行命令,./a.out parameter1 parameter2,argc的值是 3,argv[0]是"./a.out",argv[1]是"parameter1",argv[2]是"parameter2"。

    参数缺少提示
    stderr是linux里的标准输出(设备)文件,对应终端屏幕。

    fprintf是用于文件操作。

    原型:int fprintf(FILE *stream,char *format,[argument]);

    功能:fprintf()函数根据指定的format(格式)发送信息(参数)到由stream(流)指定的文件.因此fprintf()可以使得信息输出到指定的文件。

    即这里将会在屏幕上提示“usage: argv[0]

    同时退出程序,exit(0)是正常退出,代码一切正常的时候的退出。

    C语言中的fscanf和fprint函数

    stderr和stdout详细解说

    学两个单词:usage <n.>惯用法,domain name域名,dotted-decimal点分十进制

    memset
    void *memset(void *s,int c,size_t n) 将已开辟内存空间 s 的首 n 个字节的值设为值 c,即给内存赋值。

    memset用法详解

    addrinfo结构体原型

    这里使用memset是将struct addrinfo hints整个结构清0,再选择性设置一些字段。

    将ai_family设置为AF_INET可以将套接字地址结构体列表全部限制为IPV4。

    ai_socktype设置为SOCK_STREAM将列表限制为只有一个addrinfo结构。 如果不限制默认会返回三个addrinfo结构,即将TCP、UDP、原始数据报三种套接字都返回了,在使用时,遍历这个列表尝试每个类型的套接字地址,直到成功连接。

    调用getaddrinfo函数,host参数由用户输入,可以是域名也可以是点分十进制的数字地址。service参数为空,即不将服务名传化成地址。同时将设置了ai_family和ai_socktype字段的hints传入,用于对返回的套接字地址列表进行控制。

    如果调用失败,通过错误代码打印错误消息字符串。并退出程序。

    exit(1)是异常退出,在不应该出现的分枝,要求终止程序的时候就用exit(1)

    设置getnameinfo的flags为NI_NUMERICHOST,不会返回域名而是数字地址字符串
    遍历列表中的每一个addrinfo结构体,对每个结构体调用getnameinfo。不需要返回服务字段
    freeaddrinfo释放列表。
    总结:在用C语言使用windows socket时,主机和服务的转化需要程序员借助其他函数(比如pton,ntop)手动完成,而getaddrinfo和getnameinfo提供了更高级别、独立于任何特殊地址格式的抽象。这也体现了计算机领域很有名的一句话:任何问题都可以通过加一层抽象层来解决。

    11.4.8套接字接口的辅助函数

    open_clientfd建立与服务器的连接,该服务器运行在主机hostname上,并在端口port上监听连接请求。

    open_listenfd打开和返回一个监听描述符,准备好在端口port上接收连接请求。

    值得注意的是,通过这两个辅助函数所有代码都与任何版本的IP无关。

    echo客户端和服务器的示例

    include "csapp.h"

    int main(int argc, char **argv)
    {
    int clientfd;
    char *host, *port, buf[MAXLINE];
    rio_t rio;

    if (argc != 3) {
    fprintf(stderr, "usage: %s <host> <port>
    ", argv[0]);
    exit(0);
    }
    host = argv[1];
    port = argv[2];
    
    clientfd = Open_clientfd(host, port);
    Rio_readinitb(&rio, clientfd);
    
    while (Fgets(buf, MAXLINE, stdin) != NULL) {
    Rio_writen(clientfd, buf, strlen(buf));
    Rio_readlineb(&rio, buf, MAXLINE);
    Fputs(buf, stdout);
    }
    Close(clientfd);
    exit(0);
    

    }

  • 相关阅读:
    HTTP 03 HTTP 报文头
    HTTP 02 HTTP1.1 协议
    HTML 01 请求过程
    Java_异常_04_ OutOfMemoryError系列
    mq_学习_01_消息中间件的概述
    mq_学习_00_资源帖
    Java钉钉开发_异常_01_error code:50002, error message:请求的员工userid不在授权范围内
    Java_JS_01_java调用js
    JavaUtil_09_email_使用 commons-email 发送邮件
    JavaUtil_08_StringUtil_commons-lang3 之 StringUtils
  • 原文地址:https://www.cnblogs.com/clever-universe/p/7834955.html
Copyright © 2011-2022 走看看