您的位置:首页 > 产品设计 > UI/UE

apue和unp的学习之旅02——理解常用协议的原理

2014-03-18 16:25 253 查看
// --------------------------------1.常用协议简介--------------------------------------------

IPv4  (网际协议版本4) 使用32位地址, 给TCP,UDP,SCTP,ICMP和IGMP提供分组递送服务

IPv6  (网际协议版本6) 使用128地址,  给TCP,UDP,SCTP和 ICMPv6 提供分组递送服务。

TCP   (传输控制协议),面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字是一种流套接字(stream socket )。TCP既可以去使用IPv4也可以使用IPv6

UDP   (用户数据报协议), UDP是一种无连接协议。UDP套接字是一种数据报套接字(datagram socket)。

SCTP  (流控制传输协议),SCTP是一个提供可靠全双工关联的面向连接的协议。

ICMP  ( 网际控制消息协议),ICMP处理在路由器和主机之间流通的错误和控制消息。这些消息通常由TCP/IP网络支持软件本身(而不是用户进程)产生和处理,不过ping和traceroute程序同样使用ICMP。

IGMP  (网际组管理协议) IGMP用于多播。

ARP   (地址解析协议)ARP把一个IPv4地址映射成硬件地址,如以太网地址。

RARP  (反向地址解析协议)ARP把一个硬件地址映射成IPv4地址。

//-------------------------------- 2.UDP 协议的一些细节--------------------------------------

每个UDP数据报都有一个长度。如果一个数据报正确地到达目的地,那么该数据报的长度将随数据一道传递给接收端应用进程。这一点不同于TCP这个字节流协议,没有任何记录边界。(但是IP的首部有长度字段)

UDP提供无连接的服务,因为UDP客户与服务器之间不必存在任何长期的关系。

// --------------------------------3.TCP 协议的一些细节--------------------------------------

TCP不仅提供客户与服务器之间的连接,还提供了可靠性,因为当TCP向对端发送数据时,它要求对端返回一个确认,如果没收到确认,TCP就自动重传数据并等待更长时间,在数次重传失败后,TCP才放弃。 

但也不能被描述成100%可靠的协议,它提供的是数据的可靠递送或故障的可靠通知。TCP要么尽力把数据递送到对方端点,否则就通过放弃重传并中断连接来通知用户。

TCP含有用于动态估算客户与服务器之间的往返时间(RTT,round-trip time)的算法,以便它知道等待一个确认需要多少时间。因为RTT受网络流通各种变化因素影响,TCP还持续估算一个给定连接的RTT。

TCP含有序列号机制,通过给其中每个分节关联一个序列号对所发送的数据进行排序。如果这些分节非顺序到达,接收端TCP将先根据它们的序列号重新排序,如果接收端TCP接收到来自对端的重复数据,它可以根据序列号判定数据是重复的,从而丢弃重复数据。

TCP提供流量控制,TCP总是告知对端在任何时刻它一次能够从对端接收多少字节的数据,这称为通告窗口,该窗口指出接收缓冲区中当前可用的空间量,确保发送端发送的数据不会使接收缓冲区溢出。

TCP连接是全双工的,这意味着在一个给定的连接上应用可以在任何时刻在进出两个方向上既发送数据又接收数据。因此,TCP必须为每个数据流方向跟踪诸如序列号和通告窗口大小等状态信息。

// -----------------------------------4.SCTP 协议的一些细节--------------------------------------

SCTP在客户和服务器之间提供关联(association),并像TCP那样给应用提供可靠性,排序,流量控制以及全双工的数据传送。

与TCP不同的是它不是面向流的,而是面向消息的,它提供各个记录的按序递送服务,与UDP一样,由发送端写入的每条记录长度随数据一道传递给接收端应用。

SCTP提供所连接的端点之间多个流,每个流各自可靠地按序递送消息,一个流上某个消息的丢失不会阻塞同一关联其他流上的投递。这种做法与TCP相反,就TCP而言,在单一字节流中任何

位置字节丢失都将该连接上其后所有数据的递送,直到该丢失被修复为止。

SCTP还提供多宿的特性,使得单个SCTP端点能够支持多个IP地址,如果它的某个网络或某个跨越因特网的通路发生故障,SCTP就可以通过切换到使用已与该关联相关的另一个地址

来规避所发生的故障。

// ----------------------------------5.三路握手---------------------------------------

第一步:服务器被动打开(passive open)。

第二步:客户端发起主动打开(active open)。这导致客户TCP发送一个SYN分节,它告诉服务器客户端将在(待建立的)连接中发送的数据初始序列号。

第三步:服务器确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的初始数据序列号。注意,服务器在单个分节中发送SYN和对客户SYN的ACK。

第四步:客户必须确认服务器的SYN

因为这种交换一般需要(至少)3个分组,因此称之为TCP的三路握手(three-way handshake)。

ACK中的确认号是发送这个ACK的一端所期待接收的下一个序列号、(有点拗口,但是想想的确如此,下一次发送SYN的那端将以这个ACK中的确认号作为序列号)

//------------------------------------6.TCP选项--------------------------------------

每个SYN可以含有多个TCP选项

1.MSS选项,发送SYN的TCP一端使用本选项通告对端它的最大分节大小(maximum segment size)即MSS,也就是它在比呢连接的每个TCP分节中愿意接受的最大数据量。发送端TCP使用接收端

的MSS值作为所发送分节的最大大小。可以使用TCP_MAXSEG套接字选项提取和设置这个TCP选项。

2.窗口规模选项,TCP连接任何一端能够通告对端的最大窗口大小是65535,因为在TCP首部中相应的字段占16位,然而在当今因特网上越来越普及高速网络连接或长延迟路径要求有

更大的窗口以获得尽可能大的吞吐量。这个新选项指定TCP首部中的通告窗口必须扩大(即左移)的位数。在一个TCP连接上使用窗口规模的前提是它的两个端系统必须都支持这个选项。可以使用SO

_RECVBUF套接字选项影响这个TCP选项。

3.时间戳选项,对于高速网络连接是必要的,防止由失而复现的分组(由暂时的路由原因造成的迷途的分组,当路由稳定后,它又会正常到达目的地,其前提是他它们在此前尚未被路由器

丢弃)因为高速网络中32位序列号短时间内就可能循环一轮重新使用,若不使用时间戳选项,失而复现的分组所承载的分节可能与再次使用相同序列号的真正分节发生混淆)造成数据破坏。

//----------------------------------7.TCP连接终止-------------------------------------

第一步:某个应用进程首先调用close,即该端执行主动关闭(active close),该端的TCP于是会发送一个FIN分节,表示数据发送完毕。

第二步:接收到这个FIN的对端执行被动关闭(passive close),这个FIN由对端的TCP确认,它的接收也作为一个文件结束符传递给接收端应用进程(放在已排队等候该应用进程接收

的任何其他数据之后),因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可以接收。

第三步:一段时间后,接收到这个文件结束符的应用进程调用close关闭它的套接字,这导致它的TCP也发送一个FIN。

第四步:主动关闭的那端的TCP确认这个FIN。

要知道的是,当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的序号)终止时,所有打开的描述符都被关闭,这也导致任然打开的任何TCP

连接也发出一个FIN。

通常情况下客户端执行关闭,但是某些协议如HTTP/1.0 却由服务器执行主动关闭。

 

//----------------------------------------8.端口号---------------------------------------------------

端口号被划分为以下3个段:

1.众所周知的端口为0~1023,这些端口由IANA(the Internet Assigned Numbers Authority,因特网分配数值权威机构)分配和控制。这些是保留端口,这些端口只能赋予特权用户进程的套接字。分配使用这些端口的服务器(例如FTP服务器,21,web服务器80)必须以超级用户特权启动。

2.已登记的端口1024~49151,这些端口不受IANA控制,不过由IANA登记并提供它们的使用情况清单。

3.49151~65535里的端口号是动态的或私有的端口。IANA不管这些端口,它们也被称为临时端口。客户端通常使用短期存活的临时端口,客户无需关心端口值,而只要确保该端口号在所在主机中的唯一性即可。传输协议的代码确保这种唯一性。

 

// -------------------------------------9.缓冲区大小限制--------------------------------------------

1.IPv4数据报的最大大小是65535,包括IPv4首部。这是因为其总长度字段占据16位决定的。而IPv6数据报的最大大小是65575字节,包括40字节的IPv6首部。

2.许多网络有一个可由硬件规定的MTU,比如,以太网的MTU是1500字节。另有一些链路(例如使用PPP协议的点对点链路)其MTU可人为配置。IPv4要求的最小链路MTU是68字节,因为这允许最大的IPv4首部(20字节固定长度部分 + 最多40字节的选项部分 + 8字节为单位的的片段偏移字段);而IPv6要求的最小链路MTU是1280字节,IPv6可以运行在MTU小于此最小值的链路上,不过需要特定于链路的分片和重组功能,以使得这些链路看起来具有至少为1280字节的MTU。两个主机之间相反的两个方向路径的MTU可以不一致,因为在因特网中路由选择往往是不对称的。

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

4.IPv4首部的DF位(不分片位,don't fragment bit)若被设置,那么不管是发送这些数据报的主机还是转发它们的路由器都不允许对它们分片。当路由器接收到一个超过其外出链路MTU大小且设置了DF位的IPv4数据报时,它将产生一个ICMPv4出错信息(destination unreachable,fragmentation needed but DF bit set)。

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

6.IPv4和IPv6都定义了最小重组缓冲区大小,它是IPv4或Ipv6的任何实现都必须支持的最小数据报大小。其值对于IPv4为576字节,对于IPv6为1500字节。

7.TCP有一个MSS选项,用于向对端TCP通告对端在每个分节中能发送的最大TCP数据量。MSS的目的是告诉对端其重组缓冲区大小的实际值,从而试图避免分片。MSS经常设置成MTU减去IP和TCP首部的固定长度。在以太网中使用IPv4的MSS值为1460,使用IPv6的MSS值为1440

 

//----------------------------------10.TCP write输出-----------------------

1.每一个TCP套接字有一个发送缓冲区,而不能理解成众多套件字共享TCP的一个发送缓冲区,我们可以使用SO_SNDBUF套接字选项来更改该缓冲区的大小。当某个应用进程调用write时,内核从该应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区。如果该套接字的发送缓冲区容不下该应用进程的所有数据(或是应用进程的缓冲区大于套接字发送缓冲区,或是套接字的发送缓冲区中已有其他数据),该应用进程将被投入睡眠。内核将不从write系统调用返回,直到应用进程缓冲区中的所有数据都复制到套接字发送缓冲区。因此,write调用成功返回仅仅表明我们可以重新使用原来的应用进程缓冲区,并不表明对端的TCP或应用进程已收到数据。对端TCP必须确认收到的数据,伴随来自对端的ACK的不断到达,本端TCP至此才能从套接字发送缓冲区中丢弃已确认的数据。注意,套接字发送缓冲区中的数据可能被TCP提取多次而行成多个TCP分节,至于提取多少次会受到对端告知的MSS的大小的影响,本端TCP以MSS或更小的块提取套接字发送缓冲区中的数据发送给对端TCP,
果对端没有发送一个MSS选项,那么取536这个值。536是IPv4最小重组缓冲区字节数减掉TCP和IP各自20字节的首部大小的结果。

2.IP给每个TCP分节安上一个IP首部以构成IP数据报,并按照其目的IP地址查找路由表项以确定外出接口,然后把数据报传递给相应的数据链路。IP可能在把数据报传递给数据链路之前将其分片,不过我们已经谈到MSS选项的目的之一就是试图避免分片。较新的实现还使用了路径MTU发现功能。

3.每个数据链路都有个输出队列,如果该队列已满,那么新到的分组将被丢弃,并沿着协议栈向上返回一个错误:从数据链路到IP,再从IP到TCP。TCP将注意到这个错误,并在以后某个时刻重传相应的分节。应用进程并不知道这种暂时的状况。

 

// ---------------------------------11.UDP sendto 输出---------------------------------------

任何UDP套接字都有发送缓冲区大小,可以使用SO_SNDBUF套接字选项更改它,不过它仅仅是可以写到该套接字的UDP数据报的大小上限。如果一个应用进程写一个大于套接字发送缓冲区大小的数据报,内核将返回该进程一个EMSGSIZE错误(不幸的是,有些UDP的实现不返回这种错误,这样甚至数据报未经发送就被丢弃的情况应用进程也不知道)。既然UDP是不可靠的,它不必保存应用进程数据的一个副本,因此无需一个真正的发送缓冲区,应用进程的数据在沿协议栈向下传递时,通常被复制到某种格式的一个内核缓冲区中,然而当该数据被发送之后,这个副本就被数据链路层丢弃了。

UDP简单地给来自用户的数据报安上8字节的首部以构成UDP数据报,然后传递给IP。如果某个UDP应用进程发送大数据报(譬如2000字节的数据报),那么它们相比TCP应用数据更有可能被分片,因为TCP会把应用数据划分成MSS大小的块,而UDP却没有对等的手段。

 

// ---------------------------------12.常见因特网的协议使用-----------------------------------

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

2.常用的路由协议有通过原始套接字而直接使用IP的OSPF路由协议,使用UDP的RIP路由协议,使用TCP的BGP协议。

3.DHCP(引导协议),SNMP(网络管理)等应用是基于UDP的。

4.SMTP(电子邮件),Telnet(远程登录),SSH(安全的远程登录),FTP(文件传送),HTTP(Web),LPR(远程登录)是基于TCP的。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: