I/O相关概念
《王道2021组原》 P283
I/O即输入/输出,输入/输出是以主机为中心而言的,将信息从外部设备传送到主机上称为输入,反之称为输出。
I/O系统中的几个基本概念如下:
- 外部设备:包括输入/输出设备和通过输入/输出接口才能访问的外存储设备。
- 接口:在各个外设与主机之间传输数据时进行各种协调工作的逻辑部件。
- 输入设备:用于向计算机系统输入命令和文本、数据等信息的部件。键盘和鼠标是最基本的输入设备。
- 输出设备:用于将计算机系统中的信息输出到计算机外部进行显示、交换等的部件。显示器和打印机是最基本的输出设备
- 外存设备:指除计算机内存及CPU缓存等以外的存储器。硬磁盘、光盘等是最基本的外存设备。
一般来说,I/O系统由I/O软件和I/O硬件两部分组成:
- I/O软件:采用I/O指令和通道指令实现CPU与I/O设备的信息交换。如驱动程序。
- I/O硬件:包括外部设备、设备控制器和接口等。通过设备控制器来控制I/O设备的具体动作:通过I/O接口与主机(总线)相连。
文件及文件操作
《CSAPP》P623
每个Linux文件都有一个类型来表明它在系统中的角色,主要有:
- 普通文件:包含任意数据。有文本文件和二进制文件两种,文本文件里存的是ascii或unicode字符的普通文件。二进制文件里面存的是二进制数据
- 目录:包含一组链接的文件。其中每个链接都将一个文件名映射到一个文件。这个文件有可能是另一个目录
- 套接字(socket):用来与另一个进程进行跨网络通信的文件。
文件有如下几种操作:
- 打开文件:进程通过调用open函数来打开一个已经存在的文件或者创建一个新文件。方式有:只读、只写、读写
- 关闭文件:进程通过调用close函数关闭一个打开的文件
- 读文件:read函数
- 写文件:write函数
在某种情况下,read和write传送的字节比应用程序要求的要少,这些不足值(short count) 不表示错误,出现这种情况的原因有:
- 读时遇到EOF:若一个文件只有20个字节,而我们以50个字节的片进行读取。这样后面的read就会通过返回不足值0来发出EOF(End of file)信号。
- 从终端读取文件:如果打开的文件是与终端相关联的(如键盘和显示器),那么每个read函数将一次传送一个文本行,返回的不足值等于文本行的大小。
- 读写socket:如果打开的文件为socket文件,则内部缓冲约束和较长的网络延迟会引起read和write返回不足值。
使用RIO(Robust I/O)包可以自动为你处理上述说到的这三种不足值。它提供了两种不同的函数:
- 无缓冲的输入输出函数
- 带缓冲的输入输出函数
共享文件
《王道2021操作系统》 P238
文件共享使多个用户(进程)共享同一个文件,系统中只需要保留该文件的一个副本。
现代常用的两种文件共享方式如下:
- 硬链接:基于索引结点的共享方式。在这种共享方式中,诸如文件的物理地址及其他的文件属性等信息,不再存放在目录项中,而是放在索引结点中。在文件目录中只设置文件名及指向相应索引结点的指针。在索引结点中还有一个链接计数count,它代表当前文件有几个用户目录链接到了本文件上。若用户删除文件,只会将count数减1,当count数减为0时,才会真正的删除文件。
- 软链接:利用符号链实现文件共享,就是windows里的快捷方式。为使用户B能共享用户A的一个文件F,可以由系统创建一个LINK类型的新文件,也取名为F,并将文件F写入用户B的目录中,以实现用户B的目录与文件F的链接。在新文件中只包含被链接文件F的路径名。当用户要访问该软链接文件时,操作系统会先读取该链接文件中的路径,然后使用该路径去访问真正的文件。
网络编程
《CSAPP》P642
客户端-服务器模型
《CSAPP》P642
每个网络应用都是基于客户端-服务器模型的。采用该模型,一个应用由一个服务器进程和多个客户端进程组成。服务器管理着某种资源,并且通过操作这种资源来为它的客户端提供某种服务。
客户端-服务器模型的基本操作是事务(transaction,不是数据库里的那个事务),一个事务有以下四步组成:
- 客户端发送请求
- 服务端收到请求,并进行处理
- 服务端给客户端返回响应
- 客户端收到响应,并进行处理。
套接字接口
《CSAPP》P652
套接字接口(socket interface)是一组函数,它们和Unix I/O函数结合起来,用于创建网络应用。
上述函数功能如下:
- getaddinfo:将主机名、主机地址、服务名和端口号等信息,通过字符串作为参数传入,返回二进制的socket信息,供下一步初始化socket对象
- socket:socket函数用来创建一个套接字描述符(socket descriptor)
- connect:客户端通过调用connect函数来建立和服务器的链接。
- bind:用来将socket地址和socket描述联系起来
- listen:服务器调用listen函数,告诉内核,这个socket是服务器socket,不是客户端。
- accept:服务器通过调用accept函数来等待来自客户端的连接请求。