网络编程学习——基本概念(一)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1、端口号

  在任何时候,多个进程可能同时使用TCP、UDP和SCTP这3种传输层协议中的任何一种。这3种协议都使用16位整数的端口号(port number)来区分这些进程。

  当一个客户想要跟一个服务器联系时,它必须标识想要与之通信的这个服务器。TCP、UDP和STCP定义了一组众所周知的端口(well-known port),用于标识众所周知的服务。例如,支持FTP的任何TCP/IP实现都把21这个众所周知的端口分配给FTP服务器。分配给简化文件传送协议(Trivial File Trqnsfer Protocol,TFTP)的是UDP端口号69。

  另一方面,客户通常使用短期存活的临时端口(ephemeral port)这些端口号通常由传输层协议自动赋予客户。客户通常不关心其临时端口的具体值,而只需确信该端口在所在主机中是唯一的就行。传输协议的代码确保这种唯一性。

  IANA(the Internet Assigned Numbers Authority,因特网已分配数值权威机构)维护着一个端口号分配状况的清单。该清单一度作为RFC多次发布:RFC 1700是这个系列的最后一个。RFC 3232给出了代替RFC 1700的在线数据库的位置。端口号被划分成以下3段。

  1. 众所周知的端口为0~1023。这些端口由IANA分配和控制。可能的话,相同端口号就分配给TCP、UDP和SCTP的同一给定服务。例如,不论TCP还是UDP端口号80都被赋予Web服务器,尽管它目前的所有实现都单纯使用TCP。

  2. 已登记的端口(registered port)为1024~49151。这些端口不受IANA控制,不过由IANA登记并提供它们的使用情况清单,以方便整个群体。可能的话,相同端口号也分配给TCP和UDP的同一给定服务。例如,6000~6063分配给这两种协议的X Window服务器,尽管它的所有实现当前单纯使用TCP。49151这个上限的引入是为了给临时端口留出范围,而RFC 1700所列出的上限为65535。

  3. 49152~65535是动态的(dynamic)或私用的(private)端口。IANA不管这些端口。它们就是我们所称的临时端口。(49152这个魔数是65536的四分之二)。

  图1-1展示了端口号的划分情况和常见的分配情况。

网络编程学习——基本概念(一)_第1张图片

图1-1 端口号的分配

  我们要注意图1-1中以下几点。

  • Unix系统有保留端口(reserved port)的概念,指的是小于1024的任何端口。这些端口只能赋予特权用户进程的套接字。所有IANA众所周知的端口都使保留端口,分配使用这些端口的服务器(例如FTP服务器)必须以超级用户特权启动。

  • 由于历史原因,源自Berkeley的实现(从4.3BSD开始)曾在1024~5000范围内分配临时端口。

  • 有少数客户(不是服务器)需要一个保留端口用于客户/服务器的认证:rlogin和rsh客户就是常见的例子。这些客户调用库函数rresvport创建一个TCP套接字,并赋予它一个在513~1023范围内未使用的端口。该函数通常先尝试绑定端口1023,若失败则尝试1022,依次类推,直到在端口513上亦或成功,亦或失败。

2、套接字对

  一个TCP连接的套接字对(socket pair)是一个定义该连接的两个端点的四元组:本地IP地址、本地TCP端口号、外地IP地址、外地TCP端口号。图啊套接字对唯一标识一个网络上的每个TCP连接。就SCTP而言,一个关联由一组本地IP地址、一个本地端口、一组外地IP地址、一个外地端口标识。在两个端点均非多宿这一最简单的情形下,SCTP与TCP所用的四元组套接字对一致。然而在某个关联的任何一个端点为多宿的情形下,同一个关联可能需要多个四元组标识(这些四元组的IP地址各不相同,但端口号是一样的)。

  标识每个端点的两个值(IP地址和端口号)通常称为一个套接字。

  我们可以把套接字的概念扩展到UDP,即使UDP是无连接的。当讲套接字函数(bind、connect、getpeername等)时,我们将指明它们在指定套接字对中的哪些值。比如,bind函数要求应用程序给TCP、UDP或SCTP套接字指定本地IP地址和本地端口号。

 

3、缓冲区大小及限制

  下面我们将介绍一些影响IP数据报大小的限制。我们首先介绍这些限制,然后就它们如何影响应用进程能够传送的数据进行综合分析。

  • IPv4数据报的最大大小是65535字节,包括IPv4头部。这是因为其总长度字节段占16位。

  • IPv6数据报的最大大小是65575字节,包括40字节的IPv6头部。这是因为其净荷长度占据16位。注意,IPv6的净荷长度字段不包括IPv6首部,而IPv4的总长度字段包括IPv4首部。

    IPv6有一个特大净荷(jumbo payload)选项,它把净荷长度字段扩展到32位,不过这个选项需要MTU(maximum transmission unit,最大传输单元)超过65535的数据链路提供支持。(这是为主机到主机的内部连接而设计的,譬如HIPPI,它们通常没有内在的MTU)。

  • 许多网络有一个可由硬件规定的MTU。举例来说,以太网的MTU为1500字节。另有一些链路(例如使用PPP协议的点到点链路)其MTU可以人为配置。较老的SLIP链路通常使用1006字节或296字节的MTU。

    IPv4要求的最小链路MTU是68字节。这允许最大的IPv4首部(包括20字节的固定长度部分和最多40字节的选项部分)拼接最小的片段(IPv4首部中片段偏移字段以8个字节为单位)。IPv6要求的最小链路MTU为1280字节。IPv6可以运行在MTU小于此最小值的链路上,不过需要特定于链路的分片和重组功能,以使得这些链路看起来具有至少为1280字节的MTU(RFC 2460)。

  • 在两个主机之间的路径中最小的MTU称为路径MTU(path MTU)。1500字节的以太网MTU是当今常见的路径MTU。两个主机之间相反的两个方向上路径MTU可以不一致,因为在因特网中路由选择往往是不对称的,也就是说从A到B的路径与从B到A的路径可以不相同。

  • 当一个IP数据报将从某个接口送出时,如果它的大小超过相应链路的MTU,IPv4和IPv6都将执行分片(fragmentation)。这些片段在到达最终目的地之前通常不会被重组(ressembling)。IPv4主机对其产生的数据报执行分片,IPv4路由器则对其转发的数据报执行分片。然而IPv6只有主机对其产生的数据报执行分片,IPv6路由器不对其转发的数据报执行分片。

  • IPv4首部的“不分片(don`t fragment)”位(即DF位)若被设置,那么不管是发送这些数据报的主机还是转发它们的路由器,都不允许对它们分片。当路由器接收到一个超出其外出链路MTU大小且设置了DF位的IPv4数据报时,它将产生一个ICMPv4“destination unreachable,fragmentation needed but DF bit set”(目的地不可达,需要分片但DF位已设置)出错消息。

    既然IPv6路由器不执行分片,每个IPv6数据报于是隐含一个DF位。当IPv6路由器接收到一个超过其外出链路MTU大小的IPv6数据报时,它将产生一个ICMPv6“packet too big”(分组太大)出错信息。

    IPv4的DF位和IPv6隐含DF位可用于路径MTU发现(IPv4的情形见RFC 1191),IPv6的情形见RFC 1981。举例来说,如果基于IPv4的TCP使用该技术,那么它将在所发送的所有数据报中设置DF位。如果某个中间路由器返回一个ICMP“destination unreachable,fragmentation needed but DF bit set”错误,TCP就减小每个数据报的数据量并重传。路径MTU发现对于IPv4是可选的,然而IPv6的所有实现要么必须支持它,要么必须总是使用最小的MTU发送IPv6数据报。

  • IPv4和IPv6都定义了最小重组缓冲区大小(minimum reassembly buffer size),它是IPv4或IPv6的任何实现都必须保证支持的最小数据报大小。其值对于IPv4为576字节,对于IPv6是1500字节。例如,就IPv4而言,我们不能判定某个给定目的地能否接受577字节的数据报。为此许多使用UDP的IPv4网络应用(如DNS、RIP、TFIP、BOOTP、SNMP)避免产生大于这个大小的数据报。

  • TCP有一个MSS(maximum segment size,最大分节大小),用于向对端TCP通告对端在每个分节中能发送的最大TCP数据量。我们看到了SYN分节上的MSS选项。MSS的目的是告诉对端其重组缓冲区大小的实际值,从而试图避免分片。MSS经常设置成MTU减去IP和TCP首部的固定长度。在以太网中使用IPv4的MSS值为1460,使用IPv6的MSS值为1440(两者的TCP首部都使20个字节,但IPv4首部为20字节,IPv6首部却是40字节)。在TCP的MSS选项中,MSS值是一个16位的字段,限定其最大值为65535。这对于IPv4是合适的,因为IPv4数据报中的最大TCP数据量为65495(65535减去IPv4首部的20字节和TCP的首部的20字节)。然而对于具有特大净荷选项的IPv6,确需要使用另外一种技巧(RFC 2675)。首先,没有特大净荷选项的IPv6数据报中的最大TCP数据量为65515(65535减去TCP首部的20字节)。65535这个MSS值于是被视为表示“无限”的一个特殊值。该值只在用到特大净荷选项时才使用,不过这种情况却要求实际的MTU超过65535。其次,如果TCP使用特大净荷选项,并且接收到的对端通告的MSS为65535,那么它所发送数据报的大小限制就是接口MTU。如果这个值太大(也就是说说在路径中某个链路的MTU比较小),那么路径MTU发现功能将确定这个较小值。

  • SCTP基于到对端所有地址发现的最小路径MTU保持一个分片点。这个最小MTU大小用于把较大的用户消息分割成较小的能够以单个IP数据报发送的若干片段。SCTP_MAXSEG套接字选项可以影响该值,使得用户能够请求一个更小的分片点。

4、标准因特网服务

  图1-2列出了TCP/IP多数实现都提供的若干标准服务。注意,表中所有服务同时使用TCP和UDP提供,并且这两个协议所用端口号也相同。

  这些服务通常由Unix主机的ineted守护进程提供。它们还提供使用标准的Telnet客户程序就能完成的简易测试机制。举例来说,下面就是时间获取和回射这两个标准服务器的测试过程:

网络编程学习——基本概念(一)_第2张图片

网络编程学习——基本概念(一)_第3张图片

网络编程学习——基本概念(一)_第4张图片

图1-2 大多数实现提供的标准TCP/IP服务

  这两个例子中,我们键入主机名和服务名(daytime和echo)。这些服务名由/etc/services文件映射到图1-2所示的端口号。

  注意,当我们连接到daytime服务器时,服务器执行主动关闭,然而当连接到echo服务器时,客户执行主动关闭。我们知道执行主动关闭的那一端就是历经TIME_WAIT状态的那一端。

  为了应付针对它们的拒绝服务攻击和其他资源使用攻击,在如今的系统中,这些简单的服务通常被禁用。

 

5、常见因特网应用的协议使用

  图1-3总结了各种常见的因特网应用对协议的使用情况。

  前两个因特网应用ping和traceroute是使用ICMP协议实现的网络诊断应用。traceroute自行构造UDP分组来发送并读取所引发的ICMP应答。

  紧接着是3个流行的路由协议,它们展示了路由协议使用的各种传输协议。OSPF通过原始套接字直接使用IP,RIP使用UDP,BGP使用TCP。

  接下来5个是基于UDP的网络应用,然后是7个TCP网络应用和4个同时使用UDP和TCP的网络应用,最后5个是IP电话网络应用,它们或者独自使用SCTP,或者选用UDP、TCP或SCTP。

网络编程学习——基本概念(一)_第5张图片

图1-3 各种常见因特网应用的协议使用情况

 

转载于:https://my.oschina.net/u/2537915/blog/654686

你可能感兴趣的:(网络编程学习——基本概念(一))