网络编程
本章的核心内容:socket编程
网络
关于网络的基本概念可以跳转到:计算机网络
套接字接口
套接字接口有什么用?
套接字接口是一组函数,和Unix IO函数结合起来,用以创建网络应用
如何使套接字结构地址适用所有协议?
将特定协议的套接字结构地址强转成通用的套接字结构地址使用
相关接口:
- socket() 创建一个新的确定类型的套接字,类型用一个整型数值标识(文件描述符),并为它分配系统资源。
- bind() 一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。
- listen() 用于服务器端,使一个绑定的TCP套接字的tcp状态由CLOSE转至LISTEN;操作系统内核为此监听socket所对应的tcp服务器建立一个pending socket队列和一个established socket队列;参数backlog指定pending socket队列的长度,0表示长度可以无限大。pending socket,就是某客户端三次握手的syn包到达,内核为这个syn包对应的tcp请求生成一个socket(状态为SYN_RECV),但三次握手还没有完成时的socket。
- connect() 用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。
- accept() 用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。
为什么要区分监听描述符和已连接描述符?
实现并发服务
getaddinfo函数有什么意义?
IPv4中使用gethostbyname()函数完成主机名到地址解析,这个函数仅仅支持IPv4,
且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储IPv4地址的空间。
IPv6中引入了新的API getaddrinfo(),它是协议无关的,既可用于IPv4也可用于IPv6。
getaddrinfo() 函数能够处理名字到地址以及服务到端口这两种转换,返回的是一个 struct addrinfo 的结构体(列表)指针而不是一个地址清单。
这些 struct addrinfo 结构体随后可由套接口函数直接使用。如此以来,getaddrinfo()函数把协议相关性安全隐藏在这个库函数内部。
应用程序只要处理由getaddrinfo()函数填写的套接口地址结构。
一个主机名可能对应多个地址
简化getaddinfo函数的使用:
综合:TINY Web 服务器
使用mmap和io读取文件区别?
总结来说,常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制(读写同一个文件时采用同一个也缓存),这个缓存在内核虚拟空间中。
这样造成读文件时需要先将文件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对应的用户空间中。这样,通过了两次数据拷贝过程,才能完成进程对文件内容的获取任务。写操作也是一样,待写入的buffer在内核空间不能直接访问,必须要先拷贝至内核空间对应的主存,再写回磁盘中(延迟写回),也是需要两次数据拷贝。
而使用mmap操作文件中,创建新的虚拟内存区域和建立文件磁盘地址和虚拟内存区域映射这两步,没有任何文件拷贝操作。而之后访问数据时发现内存中并无数据而发起的缺页异常过程,可以通过已经建立好的映射关系,只使用一次数据拷贝,就从磁盘中将数据传入内存的用户空间中,供进程使用。
总而言之,常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同数据不通的繁琐过程。
因此,可以想象,在只访问一次的情况下,mmap效率更高。