zoukankan      html  css  js  c++  java
  • 20155317 《信息安全系统设计基础》第十三周周学习总结

    20155317 《信息安全系统设计基础》第十三周周学习总结

    一、UNIX I/O

        在UNIX系统中有一个说法,一切皆文件。所有的I/O设备,如网络、磁盘都被模型化为文件,而所有的输入和输出都被当做对相应文件的读和写来执行。这种将设备映射为文件的方式,允许UNIX内核引出一个简单、低级的应用接口,称为UNIX I/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行。

    • 打开文件 打开文件操作完成以后才能对文件进行一些列的操作,打开完成过以后会返回一个文件描述符,它在后续对此文件的所有操作中标识这个文件,内核记录有关这个打开文件的所有信息。
    • 改变当前的文件位置。
    • 读写文件
    • 关闭文件 应用完成了对文件的访问之后,就通知内核关闭这个文件,内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中。进程终止,内核也会关闭所有打开的文件并释放他们的存储器资源。

    二、打开和关闭文件

        关于打开文件的基本操作,这里就不再累述,就是关于几个函数的解释,在上面的三篇文章中有解释。

        

    int open(char *filename,int flags,mode_t mode);

        其中打开标志flags有三种基本标志:O_RDONLY、O_WRONLY、O_RDWR。也可以和其他三种(O_CREAT、O_TRUNC、O_APPEND)组合使用。mode参数指定了新文件的访问权限位。(这次终于看到完全的mode参数的使用方法了)

    三、读和写文件

    在系统I/O中读写文件用的系统函数为read()和write()函数来执行。


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

        read函数从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。而write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。返回值要么为-1要么为写入的字节数目。

    #include "csapp.h"  
      
    int main(void)   
    {  
        char c;  
      
        while(Read(STDIN_FILENO, &c, 1) != 0)   
        Write(STDOUT_FILENO, &c, 1);  
        exit(0);  
    }  

        关于在文件中定位使用的函数为lseek,在I/O库中使用的函数为fseek。
        size_t和ssize_t的区别:

     

    unsign 和 没有unsign的区别:在前几次的袁征老师的密码分析学实验中,老师要求我们编写几个产生随机数的算法程序,我采取的是用斐波那契数列、线性同余等这样的数学书证明的方法去产生,但是在编写程序的时候,出现了负值的情况,也就是说产生的随机数是负值,也就是说出现了超出范围,可是在我的算法中随机值不会超过2的31次方,也就是说int或者long是完全够用的,为了避免出现上述的情况,我还特地用了long,但是还是出现了上述的错误:

    最后经过查验,这并不是程序的思想导致的,这是由于C语言的编译器在进行有符号和无符号数的运算的时候所决定的。因为每个C语言编译器的版本不一样,其所能保证的范围也是不一样的,

    后来经过修改,只要将其变成无符号的数便可以成功。

        有些情况下,read和write传送的字节比应用程序要求的要少,出现这种情况的原因如下:

    • 读时遇到EOF。此时read返回0来发出EOF信号。
    • 从终端读文本行。如果打开文件是与终端相关联,那么每个read函数将以此传送一个文本行,返回的不足值等于文本行的大小。
    • 读和写网络套接字。可能会出现阻塞现象。

        实际上,除了EOF,在读磁盘文件时,将不会遇到不足值,而且在写磁盘文件时,也不会遇到不足值。然而,如果你想创建健壮的网络应用,就必须反复调用read和write处理不足值,直到所有需要的字节都传送完毕。(

    四、用RIO包健壮地读写

        这个包会处理上面的不足,RIO提供了方便、健壮和高效的I/O。提供了两类不同的函数:

    • 无缓冲的输入输出函数 直接在存储器和文件之间传送数据,没有应用级缓冲,它们对将二进制数据读写到网络和从网络读写二进制数据尤其有用。
    • 带缓冲的输入函数

    ssize_t rio_readn(int fd,void *usrbuf,size_t n);  
      
    ssize_t rio_writen(int fd,void *usrbuf,size_t n);  

        对同一个描述符,可以任意交错地调用rio_readn和rio_writen。一个问本行的末尾都有一个换行符,那么像读取一个文本中的行数怎么办,使用read读取换行符这个方法不是很妥当,可以调用一个包装函数(rio_readineb),它从一个内部读缓冲区拷贝一个文本行,当缓冲区为空时,会自动地调用read重新填满缓冲区。也就是说,这些函数都是缓冲区操作而言的。

    五、读取文件元数据

        应用程序能够通过调用stat和fstat函数检索到关于文件的信息(有时也称为文件的元数据)

    [cpp] view plain copy
     
    #include <sys/stat.h>  
    #include <unistd.h>  
    int stat(const char *filename,struct stat *buf);  
    int fstat(int fd,struct stat *buf);

        若成功,返回0,若出错则为-1.stat以一个文件名为输入,并且填充buf结构体。fstat函数只不过是以文件描述符而不是文件名作为输入。

    struct stat {  
    #if defined(__ARMEB__)  
        unsigned short st_dev;  
        unsigned short __pad1;  
    #else  
        unsigned long  st_dev;  
    #endif  
        unsigned long  st_ino;  
        unsigned short st_mode;  
        unsigned short st_nlink;  
        unsigned short st_uid;  
        unsigned short st_gid;  
    #if defined(__ARMEB__)  
        unsigned short st_rdev;  
        unsigned short __pad2;  
    #else  
        unsigned long  st_rdev;  
    #endif  
        unsigned long  st_size;  
        unsigned long  st_blksize;  
        unsigned long  st_blocks;  
        unsigned long  st_atime;  
        unsigned long  st_atime_nsec;  
        unsigned long  st_mtime;  
        unsigned long  st_mtime_nsec;  
        unsigned long  st_ctime;  
        unsigned long  st_ctime_nsec;  
        unsigned long  __unused4;  
        unsigned long  __unused5;  
    };  

        其中st_size成员包含了文件的字节大小。st_mode为文件访问许可位。UNIX提供的宏指令根据st_mode成员来确定文件的类型:S_ISREG(),这是一个普通文件么;S_ISDIR(),这是一个目录文件么;S_ISSOCK()这是一个网络套接字么。使用一下这个函数

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string.h>  
    #include <sys/stat.h>  
    #include <sys/types.h>  
    #include <unistd.h>  
    int main()  
    {  
        int fd,size;  
        struct stat buf_stat;  
        memset(&buf_stat,0x00,sizeof(buf_stat));  
        fd=stat("stat.c",&buf_stat);  
            printf("%d
    ",(int)buf_stat.st_size);  
        return 0;  
        }  

    六、共享问价

        内核用三个相关的数据结构来表示打开的文件:

    • 描述符表(descriptor table)每个进程都有它独立的描述符表,它的表项是由进程打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个表项。
    • 文件表(file table)  打开文件的描述符表项指向问价表中的一个表项。所有的进程共享这张表。每个文件表的表项组成包括由当前的文件位置、引用计数(既当前指向该表项的描述符表项数),以及一个指向v-node表中对应表项的指针。关闭一个描述符会减少相应的文件表表项中的应用计数。内核不会删除这个文件表表项,直到它的引用计数为零。
    • v-node表(v-node table)同文件表一样,所有的进程共享这张v-node表,每个表项包含stat结构中的大多数信息,包括st_mode和st_size成员。

       下面看几张图。

       描述符1和4通过不同的打开文件表表项来引用两个不同的文件。这是典型的情况,没有共享文件,并且每个描述符对应一个不同的文件。

        多个描述符也可以通过不同的文件表表项来应用同一个文件。如果同一个文件被open两次,就会发生上面的情况。关键思想是每个描述符都有它自己的文件位置,所以对不同描述符的读操作可以从文件的不同位置获取数据。

        父子进程也是可以共享文件的,在调用fork()之前,父进程如第一张图,然后调用fork()之后,子进程有一个父进程描述符表的副本。父子进程共享相同的打开文件表集合,因此共享相同的文件位置。一个很重要的结果就是,在内核删除相应文件表表项之前,父子进程必须都关闭了他们的描述符。   

    七、标准I/O

        标准I/O库将一个打开的文件模型化为一个流。对于一个程序而言,一个流就是一个指向FILE类型的结构的指针。类型为FILE的流是对文件描述符和流缓冲区的抽象。流缓冲区的目的和RIO读缓冲区的一样:就是使开销较高的UNIX I/O系统调用的数量尽可能的小。例如,当第一次调用getc时,库通过调用一次read函数来填充流缓冲区,然后将缓冲区总的第一个字节返回给应用程序。只要缓冲区还有未读的字节,接下来对getc的调用就能直接从流缓冲区得到服务。

    八、重定向

    • I/O重定向操作符,允许用户将磁盘文件和标准输入输出联系起来。unix> ls > foo.txt
    • I/O重定向是依靠dup2函数工作的。dup2函数拷贝描述符表表项oldfd到描述符表项newfd,覆盖描述符表表项newfd以前的内容。如果newfd已经打开,dup2会在拷贝oldfd之前关闭newfd。

    九、课下练习

    10.1

    发现是库文件“csapp.h”的问题。经过修改后编译成功。

    对于“csapp.h”这个头文件,可以从网址http://download.csdn.net/detail/tzasd89812/4206284上去下载,也可以用<stdio.h><fcntl.h><unistd.h>这三个头文件等效替代。我是选择的后种方法~

    
    

     10.2:

     10.3


    10.4:

    重定向标准输入(描述符0)到描述符5,我们将调用dup2(5,0)或者等价的dup2(5,STDIN_FILENO)。

    10.5

    代码托管

    上周考试错题总结

    ( 单选题 | 1 分)
     

    实验4:实验中加载驱动程序的Linux命令是(                    )

     
    A.

    lsmod

    B.

    rmmod

    C.

    insmod

    D.

    modprobe

    正确答案: C
     
    你的答案: A
    这道题是有自己粗心导致的,没看清楚就是直接选了
     
     
    ( 单选题 | 1 分)
     

    实验3中,在Ubuntu虚拟机中编译多线程程序时,gcc使用()选项

     
    A.

    -g

    B.

    -lthread

    C.

    -pthread

    D.

    -lpthread

    正确答案: C
     
    gcc 再进行编译的时候用的是pthread

     

    实验1:mount -t nfs -o nolock 192.168.0.56:/root/share /host,其中的IP是()的IP

     
    A.

    Windows 宿主机

    B.

    Ubuntu虚拟机

    C.

    ARM实验箱

    D.

    以上都不对

    正确答案: B
     
    你的答案: C
    这个在进行运算的时候,采用的是虚拟机进行处理的,所以IP是虚拟机的Ip

    本周结对学习情况

    - 20155301
    - 结对照片
    - 结对学习内容
        - XXXX
        - XXXX
        - ...

    其他(感悟、思考等,可选)

    我认为在linux操作系统中,最重要的就是对文件的操作以及处理,不管我们要做什么,要启用什么,在linu操作系统中,全部都是用文件进行模式化处理的,所以我认为这文件操作十分重要。

    学习进度条

     代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
    目标 5000行 30篇 400小时  
    第一周 200/200 2/2 20/20  
    第二周 300/500 2/4 18/38  
    第三周 500/1000 3/7 22/60  
    第四周 300/1300 2/9 30/90  

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。 耗时估计的公式 :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    • 计划学习时间:XX小时

    • 实际学习时间:XX小时

    • 改进情况:

    (有空多看看现代软件工程 课件 软件工程师能力自我评价表)

    参考资料

     



     
  • 相关阅读:
    Python的异常处理
    flex stage.width 与stage.stageWidth的区别
    Flex timer使用 keydown事件注册到stage
    flex 事件注册和鼠标拖动
    window.open a.href打开窗口referer的问题
    java UUID的创建
    flex chrome浏览器调试flex程序
    EL表达式 requestScope initParam用法
    Java8 Lumbda表达式 初步
    jQuery 动画的执行
  • 原文地址:https://www.cnblogs.com/wxwddp/p/8052780.html
Copyright © 2011-2022 走看看