59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

1.Internet doamin socket
	1.Unix domain 数据报 socket 是可靠的,但 UDP socket 则是不可靠的;
	2.在一个 Unix domain 数据报上发送数据会在接收 socket 的数据队列为满时阻塞。与之不同的是,使用 UDP 时,
	  如果进入的数据报使接收者的队列溢出,那么数据报就会静默的被丢弃。

2.网络字节序
	IP 地址和端口都是整数值。在将这些值在网络中传递时碰到的一个问题是不同的硬件结构会以不同的顺序来存储一个多字节整数的字节。
  存储整数时先存储(即在最小内存地址处)最高有效位的被称为大端序,那么先存最低有效位的被称为小端序。小端序最值得关注的是 x86。
  其他大多数架构都是大端的。在特定主机上使用字节序被称为主机字节序。
    由于端口号和 IP 地址必须在网络中的所有主机之间传递并且需要被它们所理解,因此必须要使用一个标准的字节序。这种字节序被称为
  网络字节序,它是大端序。

  	htons();  // host to network
  	htonl();
  	ntohs();
  	ntohl();

3.数据表示
	由于数据表现上存在这些差异,因此在网络中的异构系统之间交换数据的应用程序必须要采用一些公共规则来编码数据。发送者必须根据这些规则
  来对数据进行编码,而接收者则必须要遵守同样的规则进行解码。将数据编程一个标准以便在网络上传输的过程被称为信号编码。目前,存在多种信号
  编码标准,如 XDR,CORBA以及 XML.一般来说,这些标准会为每个数据类型定义一个固定的格式(如定义了字节序和使用的位数)。除了按照所需的格式
  进行编码之外,每个数据项都需要使用额外的字段来标识其类型(以及可能的话还会加上长度).
    然而,一种比信号编码集更简单的方式通常会被采用: 将所有传输的数据编码成文本形式,其中数据项之间使用特殊的字符来分隔开,这个特定的字符
  通常是换行符。这种方法的优点是可以使用 telnet 来调试一个应用程序。 
    telnet host port
    接着可以输入一行传给应用程序的文本并查看应用程序的响应。

4.主机和服务转换函数概述
	1.二进制和人类可读的形式之间转换 IPv4 地址:已经废弃

	点分十进制与二进制之间表示形式的转换(以网了字节序转换)
	inet_aton(); // ASCII 到 网络,函数将 str 指向的点分十进制字符串转换为一个网络字节序的 IPv4 地址。
	inet_ntoa(); 

	2.在二进制和人类可读的形式之间转换 IPv4 和 IPv6 地址:
	inet_pton(); inet_ntop(); // 允许在 IPv4, IPv6 二进制地址和点分十进制或十六进制字符串之间进行转换
	inet_ntop() 的一个用途是产生 IP 地址的一个可打印的表示形式以便记录日志。有些情况下最好使用这个函数,而不是将一个 IP 地址转换为主机名,原因
  如下:
	  	1.将一个 IP 地址解析成主机名可能需要一台 DNS 服务器发送一个耗时的请求。
  		2.在一些场景中,可能并不存在一个 DNS(PTR) 记录将 IP 地址映射到对应的主机名上。

  	3.主机和服务名与二进制形式之间的转换:已过时
  		gethostbyname(); // 返回与主机名对应的二进制 IP 地址
  		getservbyname(); // 返回与服务名对应的端口号
  		gethostbyaddr();
  		getservbyport(); 

  	4.主机与服务名与二进制形式之间的转换:
  		getaddrinfo() 函数是 gethostbyname() 和 getservbyname() 2个函数的现代继承者。给定一个主机名和服务名,getaddrinfo() 会返回一组包含对应
  	  二进制 IP 地址和端口号的结构。与 gethostbyname() 不同,getaddrinfo() 会透明的处理 IPv4 和 IPv6 地址。因此使用这个函数编写不依赖 IP 版本的程序。
  	  getnameinfo() 函数执行逆向转换,即将一个 IP 地址和端口号转换成对应的主机名和服务名。

5.DNS
	在 DNS 出现之前,主机名和 IP 地址之间的映射关系是在一个手工维护的本地文件 /etc/hosts 中进行定义的。
	然而,/etc/hosts 模式的扩展性交叉,并且随着网络主机数量的增长,这个方式已经变得不大可行了。
	
	DNS 关键想法:
		1.将主机名组织在一个层级名空间中。DNS 层级中的每个节点都有一个标签(名字),该标签最多可包含63个字符,层级的根是一个无名子的节点,即"匿名节点"。
		2.一个节点的域名由该节点到根节点的路径中所有节点的名字连接而成,各个名字之间用点 (.) 分割。如 google.com 的节点是 google 的域名。
		3.完全限定域名(FQDN), 如 www.kernel.org ,标识出了层级中的一台主机。区分一个完全限定域名的方法是看名字是否已点结尾,但在很多情况下这个点会被省略。
		4.没有一个组织或系统会管理整个层级。相反,存在一个 DNS 服务器层级,每台服务器管理树的一个分枝(一个区域)。通常,每个区域都有一个主要主名字服务器。此外,
		  还包含一个或多个从名字服务器(有时候也被称为次要主名字服务器),它们在主要名字服务器崩溃时提供备份。区域本身可以被划分成一个个单独管理的更小的区域。当一台
		  主机被添加到一个区域中或者主机名到IP之间的映射关系发生了变化时,管理员负责更新本地名字服务器数据中的对应名字。
		5.当一个程序调用 getaddrinfo() 来解析一个域名时,getaddrinfo() 会使用一组库函数(resolver 库)来与本地的 DNS 服务器通信。

	递归和迭代请求:
		递归:在一个递归请求中,请求者要求服务器处理整个解析任务,包括在必要时与其他 DNS 服务器进行通信任务。

	*域:
		紧跟在匿名根节点下面的节点被称为*域(TLD)。可以分为:通用的和国家的

6./etc/services 文件
	一个给定的端口号引用 udp 和 tcp 的唯一实体,但 IANA 的策略是将两个端口都分配给服务,即使服务只是用了其中一种协议。如 telnet,ssh,http 它们只是用了 tcp,
  但对应的 udp 端口也被分配给了这些服务。
    /etc/services 文件仅仅记录着名字到数字的映射关系。它不是一种预留机制:在 /etc/services 中存在一个端口号并不能保证实际环境中特定的服务就能够绑定到该端口上。

7.独立于协议的主机和服务转换
	getaddrinfo(); // 给定一个主机和服务器名,返回一个 socket 地址结构表。
	freeaddrinfo(); // 释放 addrinfo 列表
	gai_strerror(); // 错误诊断
	getnameinfo(); 

	herror();
	getservbyname();
	getservbyport();

8.Unix 和 Internet domain socket 比较
	编写通过网络进行通信的应用必须使用 Internet domain socket .
	编写 Internet domain socket  的应用程序比较简单,因为这种程序既能运行于同一个主机,也能用于不同主机。
	用 Unix domain socket 的原因:
		1.在一些实现上,Unix domain socket 的速度比 Internet domain socket 快。
		2.可以使用目录(在 Linux 上是文件) 权限来控制对 Unix domain socket 的访问,这样只有运行于指定的用户或组ID 下的应用程序才能够连接到一个监听 socket 或向
		  一个数据报 socket 发送一个数据包,同时为如何验证客户端提供了一个简单的方法。使用 Internet domain socket 验证客户端的话就麻烦很多了
		3.使用 Unix domain socket 传递打开的文件描述符和发送者的验证信息。


	

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain

59.Linux/Unix 系统编程手册(下) -- SOCKET: Internet Domain