zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155208 《信息安全系统设计基础》第四周学习总结

    2017-2018-1 20155208 《信息安全系统设计基础》第四周学习总结

    学习任务

    • 参考教材第十章内容
    • 用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名
    • 不要把代码都写入main函数中
    • 要分模块,不要把代码都写入一个.c中
    • 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息
    • 课上上传代码到码云

    Linux下od命令的学习

    1、 od命令解释:

    用于输出文件的八进制、十六进制或其它格式码的字节,通常用于显示或查看文件中,不能直接显示在终端的字符。 常见的文件为文本文件和二进制文件。此命令主要用来查看保存在二进制文件中的值。比如,程序可能输出大量的数据记录,每个数据是一个单精度浮点数。这些数据记录存放在一个文件中,如果想查看下这个数据,这时候od命令就派上用场了。在我看来,od命令主要用来格式化输出文件数据,即对文件中的数据进行无二义性的解释。不管是IEEE754格式的浮点数还是ASCII码,od命令都能按照需求输出它们的值。

    2、参数

    命令作用
    -a 此参数的效果和同时指定"-ta"参数相同。
    -A<字码基数> 选择要以何种基数计算字码。
    -b 此参数的效果和同时指定"-toC"参数相同。
    -c 此参数的效果和同时指定"-tC"参数相同。
    -d 此参数的效果和同时指定"-tu2"参数相同。
    -f 此参数的效果和同时指定"-tfF"参数相同。
    -h 此参数的效果和同时指定"-tx2"参数相同。
    -i 此参数的效果和同时指定"-td2"参数相同。
    -j<字符数目>或--skip-bytes=<字符数目> 略过设置的字符数目。
    -l 此参数的效果和同时指定"-td4"参数相同。
    -N<字符数目>或--read-bytes=<字符数目> 到设置的字符数目为止。
    -o 此参数的效果和同时指定"-to2"参数相同。
    -s<字符串字符数>或--strings=<字符串字符数> 只显示符合指定的字符数目的字符串。
    -t<输出格式>或--format=<输出格式> 设置输出格式。
    -v或--output-duplicates 输出时不省略重复的数据。
    -w<每列字符数>或--width=<每列字符数> 设置每列的最大字符数。
    -x 此参数的效果和同时指定"-h"参数相同。
    --help 在线帮助。
    --version 显示版本信息

    实例效果:

    执行下列命令:

    echo abcdef g > tmp
     
     cat tmp
     
     od -b tmp

    运行结果如图:

    3、 用Linux IO相关系统调用编写myod.c 用myod 实现Linux下od -tx -tc :

    运行代码为:

    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include"head.h"
    
    
    int main(int argc,char *argv[])
    {
    
        int i;
        int n1=0,n2=0,n3=0,n4=0;
        for(i=1;i<argc-1;i++)
        {
            switch(argv[i][2])
            {
                case 'c':n1=1;break;
                case 'x':n2=1;break;
                case 'd':n3=1;break;
                case 'o':n4=1;break;
            }
        }
        FILE *file=fopen(argv[argc-1],"r");
        if(file==NULL){printf("Error!
    ");exit(0);}
        myod(file,n1,n2,n3,n4);
        return 0;
    }
    #include<stdio.h>
    void myod(FILE *file,int n1,int n2,int n3,int n4)
    {
        char ch,line[16];
        int i;
        int j=0;
        while((ch=fgetc(file))!=EOF){
            line[j%16]=ch;
    	if((j+1)%16==0){
            if(n1){for(i=0;i<16;i++)
            {
                if(line[i]=='
    ')
                {printf("%5s","\n");continue;}
    	    if(line[i]=='	')
                {printf("%5s","\t");continue;}
                putchar(line[i]);
                putchar(' ');
                putchar(' ');
                putchar(' ');
                putchar(' ');
            }
            putchar('
    ');}
            if(n2){for(i=0;i<16;i++)
            {
                if(line[i]=='
    ')
                {printf("0%-4x",'
    ');continue;}
    	    if(line[i]=='	')
                {printf("0%-4x",'	');continue;}
                printf("%-5x",line[i]);
            }
            putchar('
    ');
            }
    
            if(n3){for(i=0;i<16;i++)
            {
                if(line[i]=='
    ')
                {printf("%-5d",'
    ');continue;}
    	    if(line[i]=='	')
                {printf("%-5d",'	');continue;}
                printf("%-5d",line[i]);
            }
            putchar('
    ');
            }
            if(n4){for(i=0;i<16;i++)
            {
                if(line[i]=='
    ')
                {printf("%-5o",'
    ');continue;}
    	    if(line[i]=='	')
                {printf("%-5o",'	');continue;}
                printf("%-5o",line[i]);
            }
            putchar('
    ');
            }
            printf("下一行!
    ");
    	}
    	j++;
    
        }
    }

    代码编写中遇到的问题

    问题: 关于char *argv的使用。

    解决: 通过查找资料得知 argc是命令行总的参数个数 argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数 命令行后面跟的用户输入的参数;

    char *argv[]是一个字符数组,其大小是int argc,主要用于命令行参数 argv[] 参数,数组里每个元素代表一个参数;argc记录了用户在运行程序的命令行中输入的参数的个数 ;arg[]指向的数组中至少有一个字符指针,即arg[0].他通常指向程序中的可执行文件的文件名。在有些版本的编译器中还包括程序 文件所在的路径;

    教材学习内容总结

    第十章学习

    • 输入/输出(I/O)是在主存和外部设备(如磁盘驱动器、终端和网络)之间拷贝数据的过程。输入操作是从I/O设备拷贝数据到主存,而输出操作是从主存拷贝数据到I/O设备。

    10.1 Unix I/O:

    • 打开文件 1、应用程序向内核发出请求

      2、要求内核打开相应的文件

      3、内核返回文件描述符

    • 一个小的非负整数,用来在后续对此文件的所有操作中标识这个文件叫做文件描述符,有三个已经指定了的文件描述符为:

      标准输入——0(STDIN_FILENO)

      标准输出——1(STDOUT_FILENO)

      标准错误——2(STDERR_FILENO)

    • 也就是说,在Unix生命周期一开始,0、1、2就被占用,以后的open只能从3开始,并且在UNIX下还有stdin,stdout,stderr表示同样的含义。

    10.2打开和关闭文件

    • 打开文件:int open(char *filename, int flags, mode_t mode)

    • flags参数指明了进程打算如何访问这个文件:

      O_RDONLY:只读

      O_WRONLY:只写

      O_RDWR:可读可写

    • flags参数也可以是一个或者更多位掩码的或:

      O_CREAT:如果文件不存在,就创建它的一个截断的文件

      O_TRUNC:如果文件已存在,就截断它

      O_APPEND:在每次写操作前,设置文件的位置到文件的结尾处

    • 关闭文件

      int close(int fd)

    10.3读和写文件

    1、读 read

    函数原型:

    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t n);

    2、写 write

    函数原型:

    #include <unistd.h>
    ssize_t write(int fd, void *buf, size_t n);

    10.4用RIO包健壮的读写

    • 通过调用 rio_readn 和 rio_write函数,应用程序可以在内存和文件之间直接传送数据。

    • rio_readn函数在遇到EOF时只能返回一个不足值;而rio_write函数绝不会返回不同值;

    • 参数解析:

      fd:文件描述符

      usrbuf:存储器位置

      n:传送的字节数

      返回值:

      rio_readn成功则返回传送的字节数,EOF为0(一个不足值),出错为-1。

      rio_writen成功则返回传送的字节数,出错为-1,没有不足值。

    • RIO的带缓冲的输入函数

      缺点:效率不是很高,每读取文件中的一个字节都要求陷入内核

    10.5 读取文件元数据

    • 应用程序能够通过调用stat和fstat函数,检索到关于文件的信息:元数据

    • 两种输入方式:

      stat函数以一个文件名作为输入

      fstat函数以文件描述符作为输入

    • stat数据结构中的st_size成员包含了文件的字节数大小,st_mode成员编码了文件访问许可位和文件类型。

    10.6 共享文件

    内核用三个相关的数据结构来表示打开的文件:
    • 描述符表:每个进程都它独立的描述符表,每个打来的描述符表指向文件表中的一个表项。
    • 文件表:打开文件的集合是由一张文件表来表示的。
    • v-node表:所有进程共享,每个表项包含stat结构中的大多数信息

    10.7 I/O重定向

    • 使用dup2函数:

      int dup2(int oldfd,int newfd);

    • dup2函数拷贝描述符表表项oldfd到描述符表表项newfd

    10.8 标准I/O

    • 标准I/O库将一个打开的文件模型化为一个流,一个流就是一个指向FILE类型的结构的指针

    • ANSI C程序开始时有三个打开的流:标准输入stdin、标准输出stdout和标准错误stderr

    • 类型为FILE的流是对文件描述符和流缓冲区的抽象

    附录A 错误处理

    错误处理风格

    • Unix风格

    遇到错误后返回-1,并且将全局变量errno设置为指明错误原因的错误代码;

    如果成功完成,就返回有用的结果。

    • Posix风格

    返回0表示成功,返回非0表示失败;

    有用的结果在传进来的函数参数中。

    • DNS风格

    有两个函数,gethostbyname和gethostbyaddr,失败时返回NULL指针,并设置全局变量h_errno。

    完成head,tail的使用,相关API的分析,伪代码,产品代码,测试代码的编写

    • head命令用来查看文件的前几行内容,默认是查看前10行的内容,也可以设置一个数字改变查看行数

    head hello.c/*当前目录下的文件名称*/

    head -20 hello.c

    • tail命令用来查看文件的最后几行内容,默认是查看最后10行的内容,同样,也可以设置一个数字改变查看行数

    tail -20 hello.c 运行代码效果如图:

    代码:

    #ifndef HEAD_H
    #define HEAD_H
    void main(int argc,char *argv[]);
    void ihead(char *ch[],int n);
    #endif
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>
    #include"head.h"
    #define N 1000
    void main(int argc,char *argv[])
    {
    	char ch[N];
    	int i,find,n;
    	if((find=open(argv[1],O_RDONLY))==-1)
    		{
    			perror(argv[1]);
    			exit(1);
    		}
    	n=read(find,ch,N);
    	ihead(ch,n);
    	close(find);
    }
    #include<stdio.h>
    #include"head.h"
    void ihead(char *ch[],int n)
    {
    	int k,count=0;
    	for(k=0;k<n,count<10;i++)
    	{
    		if(ch[k]!='
    ') 
    		printf("%c",ch[k]);
    		else {
    			count++;
    			printf("
    ");
    		}
    	}
    }

    代码托管

    码云链接

    学习进度条

     代码行数(新增/积累)博客量(新增/积累学习时间(新增/累积)
    目标 5000行 30篇 400小时
    第一周 5/5 1/1 8/8
    第二周 120/120 1/1 12/12
    第三周 100/100 1/1 15/15
    第四周 80/80 1/1 9/9

    参考资料

    《深入理解计算机系统V3》学习指导

    详细介绍Linux指令od

  • 相关阅读:
    python 中 time 模块 格式化 format
    python 以标准输出(sys.stdout)为例,看python的标准输入、标准错误输出
    Quick-lua3.3之listview
    健身计划表
    quick-cocos2d-x 实现在lua里面完成android支付宝的接入
    lua table 排序--满足多条件排序
    lua 操作中文字符串之截取和长度竖排显示
    ClippingNode实现新手引导高亮裁切
    quick cocos2dx lua 内存释放
    cocos2d-x的lua脚本加载CocostudioUI两种方式
  • 原文地址:https://www.cnblogs.com/xuzihan/p/7672584.html
Copyright © 2011-2022 走看看