互联网TCPIP协议套件
2022-10-14 15:30:40 阿炯

互联网协议套件(英语:Internet Protocol Suite,缩写IPS)是网络通信模型,以及整个网络传输协议家族,为网际网络的基础通信架构。它常通称为TCP/IP协议族(英语:TCP/IP Protocol Suite,或TCP/IP Protocols),简称TCP/IP。因为该协议家族的两个核心协议:TCP(传输控制协议)和IP(网际协议),为该家族中最早通过的标准。由于在网络通讯协议普遍采用分层的结构,当多个层次的协议共同工作时,类似计算机科学中的堆栈,因此又称为TCP/IP协议栈(英语:TCP/IP Protocol Stack) 。这些协议最早发源于美国国防部(缩写为DoD)的ARPA网项目,因此也称作DoD模型(DoD Model)。这个协议族由互联网工程任务组负责维护。

TCP/IP提供了点对点链接的机制,将资料应该如何封装、寻址、传输、路由以及在目的地如何接收,都加以标准化。它将软件通信过程抽象化为四个抽象层,采取协议堆栈的方式,分别实现出不同通信协议。协议族下的各种协议,依其功能不同,分别归属到这四个层次结构之中,常视为是简化的七层OSI模型,下为OSI的七层架构图。


1983年1月1日,在因特网的前身(ARPA网)中通信方式换成新的定义,TCP/IP取代旧的网络控制协议(NCP,Network Control Protocol),从而成为今天的互联网的基石。最早的TCP/IP由文顿·瑟夫和罗伯特·卡恩两位开发,慢慢地通过竞争战胜其他一些网络协议的方案,比如国际标准化组织ISO的OSI模型。TCP/IP的蓬勃发展发生在1990年代中期。当时一些重要而可靠的工具的出世,例如页面描述语言HTML和浏览器Mosaic,促成了互联网应用的飞速发展。 随着互联网的发展,目前流行的IPv4协议(网际协议版本四)已经接近它的功能上限。IPv4最致命的两个缺陷在于:
1.地址只有32位,IP地址空间有限;
2.不支持服务质量(Quality of Service,QoS)的想法,无法管理带宽和优先级,故而不能很好的支持现今越来越多实时的语音和视频应用。因此IPv6(网际协议版本六)浮出水面,用以取代IPv4。

TCP/IP成功的另一个因素在于对为数众多的低层协议的支持。这些低层协议对应OSI模型中的第一层(物理层)和第二层(数据链路层)。每层的所有协议几乎都有一半数量支持TCP/IP,例如:以太网(Ethernet)、令牌环(Token Ring)、光纤数据分布接口(FDDI)、点对点协议(PPP)、X.25、帧中继(Frame Relay)、ATM、Sonet、SDH等通信方法中都可以应用。


开发背景

最初想到让不同电脑之间实现连接的,是美国加州大学洛杉矶分校网络工作小组的斯蒂芬·克罗克(Stephen D. Crocker)。1970年,克罗克及其小组着手制定最初的主机对主机通信协议,它称为网络控制协议(Network Control Protocol,缩写NCP)。该协议用于阿帕网,并在局部网络条件下运行稳定,但随着阿帕网用户的增多,NCP逐渐暴露出两大缺陷:
1.NCP只是一台主机对另一台主机的通讯协议,并未给网络中的每台电脑设置唯一的地址,结果就造成电脑在越来越庞大的网络中难以准确定位需要传输数据的对象。
2.NCP缺乏纠错功能,这样一来,数据在传输过程中一旦出现错误,网络就可能停止运行。出错电脑增多,使得网络运行效率大打折扣。

在构建阿帕网先驱之后,DARPA开始其他数据传输技术的研究。NCP诞生后两年,1972年,罗伯特·卡恩(Robert E. Kahn)受雇于DARPA的信息技术处理办公室,在那里他研究卫星数据包网络和地面无线数据包网络,并且意识到能够在它们之间沟通的价值。在1973年春天,已有的ARPANET网络控制程序(NCP)协议的开发者文顿·瑟夫(Vinton Cerf)加入到卡恩为ARPANET设计下一代协议而开发开放互连模型的工作中。到了1973年夏天,卡恩和瑟夫很快开发出基本的改进形式,其中的网络协议之间的差异通过使用公用互联网协议而隐藏起来,且可靠性由主机保证而不是ARPANET那样由网络保证。瑟夫称赞了Hubert Zimmerman和Louis Pouzin(CYCLADES网络的设计者)在这个设计上发挥重要影响。

由于网络的作用减少到最小的程度,更有可能将任何网络连接到一起,而不用管它们不同的特点,这样能解决卡恩最初的问题。流行的说法提到瑟夫和卡恩工作的最终产品TCP/IP将在运行“两个罐子和一根弦”上,实际上它已经用在信鸽上。一个称为网关(后来改为路由器以免与网关混淆)的计算机为每个网络提供一个接口并且在它们之间来回传输数据包。这个设计思想更细的形式由瑟夫在斯坦福的网络研究组的1973年–1974年期间开发出来。处于同一时期诞生PARC通用包协议组的施乐PARC早期网络研究工作也有着重要的技术影响;人们在两者之间摇摆不定。DARPA于是与BBN、斯坦福和伦敦大学签署协议开发不同硬件平台上协议的运行版本。有四个版本开发出来——TCP v1、TCP v2、在1978年春天分成TCP v3和IP v3的版本,后来就是稳定的TCP/IP v4——目前因特网仍然使用的标准协议。

1975年,两个网络之间的TCP/IP通信在斯坦福和伦敦大学(UCL)之间进行测试。1977年11月,三个网络之间的TCP/IP测试在美国、英国和挪威之间进行。在1978年到1983年间,其他一些TCP/IP原型在多个研究中心之间开发出来。ARPANET完全转换到TCP/IP在1983年1月1日发生。1984年,美国国防部将TCP/IP作为所有计算机网络的标准。1985年,因特网架构理事会举行为期三天有250家厂商代表参加的关于计算产业使用TCP/IP的工作会议,帮助协议的推广并且引领它日渐增长的商业应用。

所有的TCP/IP应用都必须实现IP和ICMP。对于一个路由器(router)而言,有这两个协议就可以运作,虽然从应用的角度来看,这样一个路由器意义不大。实际的路由器一般还需要运行许多“推荐”使用的协议,以及一些其他的协议。几乎所有连接到互联网上的电脑上都存在的IPv4协议出生在1981年,今天的版本和最早的版本并没有多少改变。升级版IPv6的工作始于1995年,目的在于取代IPv4。ICMP协议主要用于收集有关网络的信息查找错误等工作。


TCP/IP参考模型

TCP/IP参考模型是一个抽象的分层模型,这个模型中,所有的TCP/IP系列网络协议都归类到4个抽象的“层”中。每一抽象层创建在低一层提供的服务上,并且为高一层提供服务。完成一些特定的任务需要众多的协议协同工作,这些协议分布在参考模型的不同层中的,因此有时称它们为一个协议栈。TCP/IP参考模型为TCP/IP协议栈订身制作。其中IP协议只关心如何使得数据能够跨越本地网络边界的问题,而不关心如何利用传输媒体,数据如何传输。整个TCP/IP协议栈则负责解决数据如何通过许许多多个点对点通路(一个点对点通路,也称为一“跳”, 1 hop)顺利传输,由此不同的网络成员能够在许多“跳”的基础上创建相互的数据通路。如想分析更普遍的网络通信问题,ISO的OSI模型也能起更好的帮助作用。因特网协议族是一组实现支持因特网和大多数商业网络运行的协议栈的网络传输协议。它有时也称为TCP/IP协议组,这个名称来源于其中两个最重要的协议:传输控制协议(TCP)和因特网协议(IP),它们也是最先定义的两个协议。同许多其他协议一样网络传输协议也可以看作一个多层组合,每层解决数据传输中的一组问题并且向使用这些低层服务的高层提供定义好的服务。高层逻辑上与用户更为接近,所处理数据更为抽象,它们依赖于低层将数据转换成最终能够进行实体控制的形式。网络传输协议能够大致匹配到一些厂商喜欢使用的固定7层的OSI模型。然而这些层并非都能够很好地与基于IP的网络对应(根据应用的设计和支持网络的不同它们确实是涉及到不同的层)并且一些人认为试图将因特网协议组对应到OSI会带来混淆而不是有所帮助。

因特网协议栈中的层

人们已经进行一些讨论关于如何将TCP/IP参考模型映射到OSI模型。由于TCP/IP和OSI模型组不能精确地匹配,还没有一个完全正确的答案。另外,OSI模型下层还不具备能够真正占据真正层的位置的能力;在传输层和网络层之间还需要另外一个层(网络互连层)。特定网络类型专用的一些协议应该运行在网络层上,但是却运行在基本的硬件帧交换上。类似协议的例子有ARP和STP(用来保持冗余网桥的空闲状态直到真正需要它们)。然而,它们是本地协议并且在网络互连功能下面运行。不可否认,将两个组(更不用说它们只是运行在如ICMP等不同的互连网络协议上的逻辑上的网络层的一部分)整个放在同一层会引起混淆,但是OSI模型还没有复杂到能够做更好的工作。 下面的图表试图显示不同的TCP/IP和其他的协议在最初OSI模型中的位置:
7应用层
application layer
例如HTTP(超文本传输协议)、SMTP(简单邮件传输协议)、SNMP(简单网络管理协议)、FTP(文件传输协议)、Telnet、SIP(会话发起协议)、SSH、NFS(网络文件系统)、RTSP、XMPP、Whois、ENRPTLS(传输层安全性协议)。
6表示层
presentation layer
例如XDR(外部数据表示法)、ASN.1、NCP(网络控制协议)、TLS、ASCII。
5会话层
session layer
例如ASAP、ISO 8327/CCITT X.225、RPC、NetBIOS、Winsock、BSD sockets(Berkeley套接字)、SOCKS、PAP。
4传输层
transport layer
例如TCP(传输控制协议)、UDP(用户数据报协议)、RTP(实时传输协议)、SCTP(流控制传输协议)、SPX(串行分组交换)、ATP(AppleTalk)。
3网络层
network layer
例如IP(网际协议)、ICMP(互联网控制消息协议)、IPX(互联网分组交换协议)、BGP(边界网关协议)、OSPF、RIP(路由信息协议)、IGRP、EIGRP、ARP(地址解析协议)、RARP、X.25。
2数据链路层
data link layer
例如以太网、令牌环、HDLC、帧中继、ISDN、ATM(异步传输模式)、IEEE 802.11、FDDI、PPP(点对点协议)。
1物理层
physical layer
例如调制解调器、无线电、光纤。


通常人们认为OSI模型的最上面三层(应用层、表示层和会话层)在TCP/IP组中是一个应用层。由于TCP/IP有一个相对较弱的会话层,由TCP和RTP下的打开和关闭连接组成,并且在TCP和UDP下的各种应用提供不同的端口号,这些功能能够由单个的应用程序(或者那些应用程序所使用的库)增加。与此相似的是,IP是按照将它下面的网络当作一个黑盒子的思想设计的,这样在讨论TCP/IP的时候就可以把它当作一个独立的层:
4应用层
application layer
例如HTTP(超文本传输协议)、FTP(文件传输协议)、DNS、BGP(边界网关协议)和RIP(路由信息协议)这样的路由协议,尽管由于各种各样的原因它们分别运行在TCP和UDP上,仍然可以将它们看作网络层的一部分。
3传输层
transport layer
例如TCP(传输控制协议)、UDP(用户数据报协议)、RTP、SCTP、OSPF这样的路由协议,尽管运行在IP上也可以看作是网络层的一部分。
2网络互连层
internet layer
对于TCP/IP来说这是因特网协议(IP)如ICMP(互联网控制消息协议)和IGMP(因特网组管理协议)这样的必须协议尽管运行在IP上,也仍然可以看作是网络互连层的一部分;ARP(地址解析协议)不运行在IP上。
1网络访问(链接)层
Network Access (link) layer
例如以太网、Wi-Fi、MPLS(多协议标签交换)等。


两个因特网主机通过两个路由器和对应的层连接。各主机上的应用通过一些数据通道相互执行读取操作。



RFC 1122中描述的沿着不同的层应用数据的封装递减



应用层

该层包括所有和应用程序协同工作,利用基础网络交换应用程序专用的数据的协议。应用层是大多数普通与网络相关的程序为了通过网络与其他程序通信所使用的层。这个层的处理过程是应用特有的;数据从网络相关的程序以这种应用内部使用的格式进行传送,然后编码成标准协议的格式。一些特定的程序视为在此层运行。它们提供服务直接支持用户应用。这些程序和它们对应的协议包括HTTP(万维网服务)、FTP(文件传输)、SMTP(电子邮件)、SSH(安全远程登录)、DNS(名称⇔IP地址寻找)以及许多其他协议。一旦从应用程序来的数据编码成一个标准的应用层协议,它将传送到IP栈的下一层。

在传输层,应用程序最常用的是TCP或者UDP,并且服务器应用程序经常与一个公开的端口号相联系。服务器应用程序的端口由互联网号码分配局(IANA)正式地分配,但是现今一些新协议的开发者经常选择它们自己的端口号。由于在同一个系统上很少超过少数几个的服务器应用,端口冲突引起的问题很少。应用软件通常也允许用户强制性地指定端口号作为运行参数。

链接外部的客户端程序通常使用系统分配的一个随机端口号。监听一个端口并且通过服务器将那个端口发送到应用的另外一个副本以创建对等链接(如IRC上的dcc文件传输)的应用也可以使用一个随机端口,但是应用程序通常允许定义一个特定的端口范围的规范以允许端口能够通过实现网络地址转换(NAT)的路由器映射到内部。

每一个应用层(TCP/IP参考模型的最高层)协议一般都会使用到两个传输层协议之一: 面向连接的TCP传输控制协议和无连接的包传输的UDP用户数据报文协议。 常用的应用层协议有:

运行在TCP协议上的协议:
HTTP(Hypertext Transfer Protocol,超文本传输协议),主要用于普通浏览。
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer, or HTTP over SSL,安全超文本传输协议),HTTP协议的安全版本。
FTP(File Transfer Protocol,文件传输协议),由名知义,用于文件传输。
POP3(Post Office Protocol, version 3,邮局协议),收邮件用。
SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),用来发送电子邮件。
TELNET(Teletype over the Network,网络电传),通过一个终端(terminal)登陆到网络。
SSH(Secure Shell,用于替代安全性差的TELNET),用于加密安全登陆用。

运行在UDP协议上的协议:
BOOTP(Boot Protocol,启动协议),应用于无盘设备。
NTP(Network Time Protocol,网络时间协议),用于网络同步。
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),动态配置IP地址。

其他:
DNS(Domain Name Service,域名服务),用于完成地址查找,邮件转发等工作(运行在TCP和UDP协议上)。
ECHO(Echo Protocol,回绕协议),用于查错及测量应答时间(运行在TCP和UDP协议上)。
SNMP(Simple Network Management Protocol,简单网络管理协议),用于网络信息的收集和网络管理。
ARP(Address Resolution Protocol,地址解析协议),用于动态解析以太网硬件的地址。


传输层

传输层(transport layer)的协议,能够解决诸如端到端可靠性(“数据是否已经到达目的地?”)和保证数据按照正确的顺序到达这样的问题。在TCP/IP协议组中,传输协议也包括所给数据应该送给哪个应用程序。 在TCP/IP协议组中技术上位于这个层的动态路由协议通常认为是网络层的一部分;一个例子就是OSPF(IP协议89)。TCP(IP协议6)是一个“可靠的”、面向链接的传输机制,它提供一种可靠的字节流保证数据完整、无损并且按顺序到达。TCP尽量连续不断地测试网络的负载并且控制发送数据的速度以避免网络过载。另外,TCP试图将数据按照规定的顺序发送。这是它与UDP不同之处,这在实时数据流或者路由高网络层丢失率应用的时候可能成为一个缺陷。较新的SCTP也是一个“可靠的”、面向链接的传输机制。它是面向记录而不是面向字节的,它在一个单独的链接上提供通过多路复用提供的多个子流。它也提供多路自寻址支持,其中链接终端能够以多个IP地址表示(代表多个实体接口),这样的话即使其中一个连接失败了也不中断。它最初是为电话应用开发的(在IP上传输SS7),但是也可以用于其他的应用。
 
UDP(IP协议号17)是一个无链接的数据报协议。它是一个“尽力传递”(best effort)或者说“不可靠”协议——不是因为它特别不可靠,而是因为它不检查数据包是否已经到达目的地,并且不保证它们按顺序到达。如果一个应用程序需要这些特性,那它必须自行检测和判断,或者使用TCP协议。UDP的典型性应用是如流媒体(音频和视频等)这样按时到达比可靠性更重要的应用,或者如DNS查找这样的简单查询/响应应用,如果创建可靠的链接所作的额外工作将是不成比例地大。
 
DCCP目前正由IETF开发。它提供TCP流动控制语义,但对于用户来说保留UDP的数据报服务模型。
 
TCP和UDP都用来支持一些高层的应用。任何给定网络地址的应用通过它们的TCP或者UDP端口号区分。根据惯例使一些大众所知的端口与特定的应用相联系。
 
RTP是为如音频和视频流这样的实时数据设计的数据报协议,它使用UDP包格式作为基础的会话层,然而据说它位于因特网协议栈的传输层。


网络互连层

TCP/IP协议族中的网络互连层(internet layer)在OSI模型中叫做网络层(network layer)。

正如最初所定义的,网络层解决在一个单一网络上传输数据包的问题。类似的协议有X.25和ARPANET的Host/IMP Protocol。 随着因特网思想的出现,在这个层上添加附加的功能,也就是将数据从源网络传输到目的网络。这就牵涉到在网络组成的网上选择路径将数据包传输,也就是因特网。 在因特网协议组中,IP完成数据从源发送到目的的基本任务。IP能够承载多种不同的高层协议的数据;这些协议使用一个唯一的IP协议号进行标识。ICMP和IGMP分别是1和2。 一些IP承载的协议,如ICMP(用来发送关于IP发送的诊断信息)和IGMP(用来管理多播数据),它们位于IP层之上但是完成网络层的功能,这表明因特网和OSI模型之间的不兼容性。所有的路由协议,如BGP、OSPF、和RIP实际上也是网络层的一部分,尽管它们似乎应该属于更高的协议栈。


网络访问(链接)层

网络访问(链接)层实际上并不是因特网协议组中的一部分,但是它是数据包从一个设备的网络层传输到另外一个设备的网络层的方法。这个过程能够在网卡的软件驱动程序中控制,也可以在韧体或者专用芯片中控制。这将完成如添加报头准备发送、通过实体介质实际发送这样一些数据链路功能。另一端,链路层将完成数据帧接收、去除报头并且将接收到的包传到网络层。 然而,链路层并不经常这样简单。它也可能是一个虚拟专有网络(VPN)或者隧道,在这里从网络层来的包使用隧道协议和其他(或者同样的)协议组发送而不是发送到实体的接口上。VPN和通道通常预先建好,并且它们有一些直接发送到实体接口所没有的特殊特点(例如,它可以加密经过它的数据)。由于现在链路“层”是一个完整的网络,这种协议组的递归使用可能引起混淆。但是它是一个实现常见复杂功能的一个优秀方法。(尽管需要注意预防一个已经封装并且经隧道发送下去的数据包进行再次地封装和发送)。


TCP/IP层次图:


注意它的层次顺序是“从下往上”数的,所以第一层就是最下面的一层:
1.第一层叫“链接层”(link layer),负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标记网络上的设备,所以有时候也叫 MAC 层。
2.第二层叫“网际层”或者“网络互连层”(internet layer),IP 协议就处在这一层。用 IP 地址取代 MAC 地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把 IP 地址再“翻译”成 MAC 地址就可以了。
3.第三层叫“传输层”(transport layer),这个层次协议的职责是保证数据在 IP 地址标记的两点之间“可靠”地传输,是 TCP 协议工作的层次,另外还有它的一个“小伙伴”UDP。
4.第四层叫“应用层”(application layer),由于下面的三层把基础打得非常好,所以在这一层就“百花齐放”了,有各种面向具体应用的协议。例如 SSH、FTP、SMTP 等等,当然还有如今最为常见的 HTTP。

MAC 层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的传输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。但这些名词并没有什么本质的区分,可以统称为数据包。

OSI的分层模型则有七层:
第一层:物理层,网络的物理形式,例如电缆、光纤、网卡、集线器等等;
第二层:数据链路层,它基本相当于 TCP/IP 的链接层;
第三层:网络层,相当于 TCP/IP 里的网际层;
第四层:传输层,相当于 TCP/IP 里的传输层;
第五层:会话层,维护网络中的连接状态,即保持会话和同步;
第六层:表示层,把数据转换为合适、可理解的语法和语义;
第七层:应用层,面向具体的应用传输数据。

传输控制协议TCP(Transmission Control Protocol)

在网络传输中,传输控制协议(TCP)是传输层非常重要的一个协议,所以学习TCP协议是很有必要的一件事情。TCP协议是一种可靠的、一对一的、面向有连接的一种通信协议,通常在TCP的网络请求中,在获取到对应的IP地址后,会以随机端口(1024-65535)向服务器80端口发起TCP的连接请求,这个连接会经过TCP/IP协议栈,最后到达服务器。而在建立连接这个过程中,通过一次三次握手来确定连接的建立。因为服务器端维护的只是一个端口,并没有主动建立连接的能力,所以只有客户端能主动的建立与服务器端的连接,所以TCP请求的发起者一定是为客户端。

1.TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议;
2.关于数据包丢失的情况;TCP 建立重传机制;
3.TCP 引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件;
4.和 UDP 头一样,TCP 头除了包含了目标端口和本机端口号外,还提供了用于排序的序列号,以便接收端通过序号来重排数据包;
5.TCP 单个数据包的传输流程和 UDP 流程差不多,不同的地方在于通过 TCP 头的信息保证了一块大的数据传输的完整性。

TCP 连接过程(建立连接- 传输数据 - 断开连接):


1.建立连接:通过三次握手和服务端建立连接;
2.数据传输:接收端需要对每个数据包进行确认操作,也就是接收端在接收到数据包之后,需要发送确认数据包给发送端;如果发送方没有收到接收方确认收到的消息,则默认数据包丢失,启动重新发送机制;
3.一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据;
4.最后是断开连接阶段,数据传输完毕要终止连接。涉及到最后一个阶段要四次挥手来保证双方都断开连接。


三次握手

我们知道发起连接的一定是客户端,那来看看三次握手的详细过程。


第一次握手:客户端发送SYN报文到服务器,服务器收到SYN报文之后能确定什么信息呢?信息1->,客户端发送能力是正常,信息2->服务器端明确自己的接收能力是正常。(服务器端明确的信息)

第二次握手:服务器端回应客户端的信息,将收到SYN报文中的seq数据加一,将其作为创建的ACK的数据,再设置一个新的Seq数据,将这个ACK和SYN的报文发送回客户端。在客户端收到SYN和ACK报文之后。会得到的信息为,信息1->服务器端的接收能力正常,信息2->服务器端的发送能力正常,信息3->客户端的接收能力正常。(客户端明确的信息)

第三次握手:客户端回应服务器端的信息,将收到服务器SYN信息中的Seq数据加一,将其作为新的ACK的数据。发送给服务器端,服务器收到ACK信息之后,会确定的信息。信息1->客户端的接收和发送能力正常。信息2->服务器端的接收和发送能力正常。(服务器端明确的信息)

经过三次握手之后,建立起双方之间的连接,三次握手主要的作用是来确定客户端和服务器端的发送和接收能力都正常之后才能建立连接。这里其实会有疑问,一次,两次,四次不可以嘛?根据作用来说,一次和两次肯定是不能完全让客户端和服务器端来明确对方的所有的状态信息。而四次的话,又会造成不必要的资源浪费,所以三次是最简洁明了的,确保两端都获取到对方状态信息。

这里看到的是三次的握手且主要关注点:
SYN:报文段,不能携带数据(发起建立报文,会消耗一个序列号)
Seq:全称为sequence number,序列号(第一次随机产生,后续报文中累加)很重要
ACK:报文段,可以携带数据(确认报文,如果携带数据,则会消耗一个序列号,如果不携带数据,则不会消耗序列号seq)
Ack:是ACK的序列号,根据SYN报文中的Seq来生成

第一次握手:[SYN] 为报文段的类型,可以看到报文中的Seq是一个随机产生的序列号,每一次的报文都会有自己的序列号作为标识。服务器端接收到这个SYN报文之后,知道的信息为,客户端发送了一个建立连接的SYN包,编号为N。

第二次握手:在2中有两个报文段是[SYN,ACK],SYN报文的序列号seq为一个新随机产生的序列号,而新创建的ACK报文的Ack序列号为Y。这里的意思是服务器端发出的意思是为两重,第一个是建立连接的SYN信息,有自己生成的seq。第二个是确认的ACK信息,将第一次握手收到的SYN信息中的Seq+1作为ACK的序列号,告诉客户端,收到了N这个序列号的SYN报文。

第三次握手:ACK的Ack序号为Y+1。这里的意思是确认了服务器的SYN包,Ack的序号为第二次握手中SYN包中Seq+1,因为这里的ACK报文只是确认,并没有携带数据,所以这里的seq还是第二次握手中ACK的序号。

通过三次握手的连接之后,下一次报文中的Seq序列号为第三次ACK报文中Seq+1

四次挥手

抓包工具的数据也验证了理论,所以接下来我们来看一下断开连接的四次挥手,同样从理论到验证,如下图所示


图中第一次挥手实际应为FIN和ACK

问题:四次挥手一定是客户端发起吗?

答案:这是不一定的,因为在TCP的连接中,所以只要有任何一端发起了断开的请求,对方收到响应之后做出断开请求的四次挥手,即完成了断开连接。所以断开连接的四次挥手可以为客户端发起,同样也可以由服务器端发起。

上图中为客户端发起断开连接的步骤,服务器端发起是同样的道理。

第一次挥手:客户端发送一个FIN和ACK的报文,序列号seq为传输数据包中最后一次的Seq+1,ACK的序列号Ack则为上一次ACK包中的序列号。将客户端的状态修改为FIN_WAIT1。服务器收到之后明确信息->客户端在等待关闭。

第二次挥手:服务器将收到FIN报文中的Seq数据+1作为新ACK报文的Ack,将收到的ACK报文中的Ack+1作为新报文ACK的Seq,将服务器端的状态调整为CLOSE_WAIT,然后将新的确认报文ACK发送给客户端。客户端收到之后明确信息->服务器端知晓客户端在等待关闭,同时将客户端的状态调整为FIN_WAIT2。

第三次挥手:服务器再次的发起FIN和ACK的报文,FIN的Seq是最后一次报文的Seq+1,ACK报文的Ack是最后一次ACK报文的的Ack+1,将服务器端的状态修改为LAST_ACK。客户端在收到之后明确信息->服务器端发送了最后一次,在等待关闭。

第四次挥手:客户端发起ACK报文,新的ACK报文的seq为第三次挥手收到的Ack,而Ack为收到FIN中的Seq+1,将自己的状态调整为TIME_WAIT。服务器端收到之后明确信息->客户端关闭,将服务器端的状态调整为CLOSED。而客户端在TIME_WAIT状态等待2MSL秒之后,将自己的状态调整为CLOSED。

FIN:报文段,不能携带数据(关闭报文,会消耗一个序列号)

这里说明一下两个点:
1.为什么一定要四次挥手,可以看到在关闭的时候,第二次和第三次挥手都是由被动方(图中为服务器端)发起,因为在某些时候可能传输的报文还没有传输完成,所以先通知客户端收到关闭的请求,然后确认服务器端的传输都完成之后,再发起第三次挥手,告诉客户端要断开连接。
2.为什么在最后一次挥手之后要等待2MSL再调整状态为CLOSED,两个原因,第一,是需要确定已经发出去,因为ACK报文有可能丢失,会需要重发。第二,如果立马关闭的话,有可能在下一次连接的是相同的IP和端口,为了防止旧连接和新连接的数据发生混乱,所以设置等待的时间让旧连接的数据完全关闭,这样就不会让旧连接和新连接之间数据造成混乱。

还是没有理解到,下面再详细讲解一下:
1.客户端进程发出连接释放报文,并且停止发送数据;客户端向服务端发送FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态
2.服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v; 此时,服务端就进入了CLOSE-WAIT(关闭等待)状态
3.客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)
4.服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
5.客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
6.服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。


保障数据包有效

TCP是可靠的数据连接,可是只是通过三次握手和四次挥手就一定能保证数据的传输不会出现问题嘛?当然是不可以,所以TCP通过以下的几个控制来确保数据包的传输有效。

一.校验和

1.首先将检验和置零;
2.然后将TCP伪首部部分,TCP首部部分,数据部分都划分成16位的一个个16进制数
3.将这些数逐个相加,记得溢出的部分加到最低位上,这是循环加法:0xc0a8+ 0x0166+……+0x0402=0x9b49
4.最后将得到的结果取反,则可以得到检验和位0x64b6

发送方:原码相加 ,并将高位叠加到低位,取反 ,得到反码求和结果,放入校验和
接收方:将所有原码 相加,高位叠加, 如全为1,则正确

发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化。如果收到报文段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段,这时 TCP 发送数据端超时后会重发数据。

二.确认应答+序列号

序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号Seq。

确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答,也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。

应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认(累积确认:对所有按序接收的数据的确认)。这个确认不是立即发送,通常将推迟几分之一秒。

TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。

三.超时重传

当报文发出后在一定的时间内未收到接收方的确认,发送方就会进行重传(通常是在发出报文段后设定一个闹钟,到点了还没有收到应答则进行重传),接收方获取到重复的数据之后,利用序列号识别到重复的数据,将其丢弃,再重新发送ack报文

四.流量控制

TCP根据接收端的处理能力,决定发送端的发送速度,TCP通过滑动窗口来进行流量控制。

流量窗口:因为TCP是全双工通信,通信的任意一方都会维护另一方的接收窗口(即接收方当前可用的缓存空间),数据是动态变化的,缓存空间也是动态的,也称之为滑动窗口。

五.拥塞控制

为了避免由于网络拥堵而采取的对发送方发送速率的限制称为拥塞控制

TCP 通过拥塞窗口实现拥塞避免->TCP 的每一端除了维护进行流量控制的滑动窗口外,还会维护一个拥塞窗口(cwnd),拥塞窗口就是对 TCP 发送方的发送速率进行限制的,具体来说的就是 TCP 会控制发送方发送到连接中的但是还没有被接收方确认的数据量。

通过上述的控制,这样就给数据的传输安全有了一定的保障。


UDP协议

UDP和TCP的区别

TCP 是面向连接的,UDP 是面向无连接的。所谓的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接的特性。

1.无连接,可提供可靠服务;
2.是一个简单的面向数据报的运输层协议;
3.它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达目的地;
4.UDP 不能保证数据可靠性,但是传输速度却非常快;
5.所以UDP一般应用在要求速度,但是没那么要求数据完整性的领域,比如在线视频等。

UDP:把数据包送达应用程序

UDP 中一个最重要的信息是端口号,通过端口号UDP 就能把数据包送到指定的程序;端口号会被装进 UDP 头里面,UDP 头再和原始数据包合并组成新的 UDP 数据包。与TCP相比有特性如下:
1.TCP 提供可靠交付。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。但是 TCP 号称能做到那个连接维护的程序做的事情。而 UDP 继承了 IP 包的特性,不保证不丢失,不保证按顺序到达。
2.TCP 是面向字节流的。发送的时候发的是一个流,没头没尾。IP 包可不是一个流,而是一个个的 IP 包。之所以变成了流,这也是 TCP 自己的状态维护做的事情。而 UDP 基于数据报的,一个一个地发,一个一个地收。
3.TCP 是可以有拥塞控制的。它意识到包丢弃了或者网络的环境不好了,就会根据情况调整自己的行为,看看是不是发快了,要不要发慢点。 UDP 就不会,应用让我发,我就发,管它洪水滔天。
4.TCP 其实是一个有状态服务,通俗地讲就是有记忆的,里面精确地记着发送了没有,接收到没有,发送到哪个了,应该接收哪个了,错一点儿都不行;而 UDP 则是无状态服务,发出去就发出去了。

UDP包头

当发送的 UDP 包到达目标机器后,发现 MAC 地址匹配,于是就取下来,将剩下的包传给处理 IP 层的代码。把 IP 头取下来,发现目标 IP 匹配。 IP 头里面有个 8 位协议,这里会存放,数据里面到底是 TCP 还是 UDP,当然这里是 UDP。于是如果知道 UDP 头的格式,就能从数据里面,将它解析出来。解析完成之后,传输层的工作就基本结束了,剩下的事情基本就由内核来完成了,里面的数据应该交给应用程序去处理。无论是 TCP 还是 UDP 包头里面应该有端口号,根据端口号,将数据交给相应的应用程序。
tcpip-arch23

UDP 包头有源端口号、目标端口号、长度、校验和以及数据组成。

UDP有以下三大特点:
1.沟通简单,不需要大量的数据结构、处理逻辑、包头字段。
2.它不会建立连接,虽然有端口号,但是监听在这个地方,谁都可以传给它数据,它也可以传给任何人数据,甚至可以同时传给多个人数据。
3.它不会根据网络的情况进行发包的拥塞控制,无论网络丢包丢成啥样了,它该怎么发还怎么发。

UDP的使用场景:
1.需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用。DHCP (动态主机配置协议)就是基于 UDP 协议的,一般的获取 IP 地址都是内网请求,而且一次获取不到 IP 又没事,过一会儿还可以再试。
2.不需要一对一沟通,建立连接,而是可以广播的应用。UDP 的不面向连接的功能,可以使得可以承载广播或者多播的协议。
3.需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也毫不退缩,一往无前的时候。当前很多应用都是要求低时延的,它们可不想用 TCP 如此复杂的机制,而是想根据自己的场景,实现自己的可靠和连接保证。例如直播、游戏,实时性比较重要,可以丢包但不要卡顿。

小结

IP和UDP总结主机A到主机B的过程:
1.主机A将要传输的数据---> 传输层;
2.在传输层: 要传输的数据包+ UDP ---> 组成新的UDP 数据包 ---> 传到网络层;
3.在网络层: 要传的数据包+UDP+IP---> 新的IP数据包,交到底层传到主机B
4.到主机B的网络层:拆解IP信息,将( 要传输的数据包+ UDP)传到传输层;
5.在传输层:数据包中的 UDP 头会被拆开,并根据 UDP 中所提供的端口号,把数据部分交给上层的应用程序。


TCP/IP FAQ之链路层、网络层和传输层、插口层和应用层
 
本节以经典的4.4BSD-Lite实现为准,主要参考《TCP/IP协议详解》3卷,理清主干,不深究细枝末节,皆在总结基本原理和实现。

【Data Link】
1. 环回接口地址必须是127.0.0.1吗?
形如127.x.x.x的A类IP都可作为环回接口的地址,但常用的是127.0.0.1。

2. 环回接口为什么没有输入处理?
发送到环回接口的数据报实质上被送到网络层的输入队列中,因此数据报没有离开网络,也就不可能从链路上接收到目标地址为环回接口地址的数据帧,所以不存在输入处理。

3. SLIP、环回和以太网接口,三者有何不同?
SLIP和环回接口没有链路层首部和硬件地址,环回接口没有输入处理,而以太网接口都有。

4. SLIP和以太网接口如何分用输入帧,环回接口如何分用输出分组?
SLIP将帧直接放进IP输入队列中,以太网接口则根据帧类型字段放到对应的协议输入队列中,环回接口则按目的地址族放到对应的输入队列中。

5. 接口和地址有什么关联?
一个接口的编址信息包括主机地址、广播地址和网络掩码,当内核初始化时,每个接口分配一个链路层地址,可以配置有多个相同或不同的网络层地址,例如2个IP地址,或者1个IP地址、1个OSI地址。

【ARP & RARP】
1. 何时发送ARP请求,何时应答ARP请求?
当单播发送IP数据并且查询ARP高速缓存失败时,就会广播一个询问目的主机硬件地址的ARP请求;当接收到ARP请求的主机就是该请求所要查找的目的主机或目的主机的ARP代理服务器时,就会单播一个ARP应答。

2. 为什么两者的以太网帧类型不同?
ARP值为0x0806,RARP为0x8035,其实对于发送方来说,利用ARP的op字段可以区分RARP,但对于接收方,由于ARP实现在内核中,而RARP一般实现为服务器,所以为了更易区分,就单独用另一个值标识。

3. 设计RARP服务器有哪些问题?
一是怎么发送以太网帧以响应请求,这与系统相关。二是当存在多个服务器时,同时发送响应帧会造成以太网冲突,这可以通过分主从服务器和随机延时来优化避免。

4. ARP在等待应答时,它会如何处理发往给定目的的多个报文?
在大多数的实现中,在等待一个ARP应答时,只将最后一个报文发给特定目的主机。Host Requirements RFC要求实现中必须防止这种类型的ARP洪泛,建议最高速率是每秒一次。

5. 免费ARP有什么作用?
一般的ARP请求用于查询目标硬件地址,并等待应答。而免费的ARP发出请求并不一定期望应答,这可以有两方面的作用:
1)一个主机可以确定是否存在相同IP地址的另一主机;
2)当本机硬件地址改变时,通知其它主机更新ARP高速缓存。

6. ARP如何映射一个IP多播地址?
先获取IP多播地址的低23位,再与常量0x01005e7f0000按位或,结果就是对应的多播硬件地址。

【IP】
1. 何时何地分片?
当数据报长度大于链路接口MTU且DF=0时,开始分片,分片可发生在源主机,也可发生在中途路由器。若需要分片但DF=1,则向源主机发送ICMP不可达差错。

2. 如何分片?
1)计算每个分片的数据长度(不含IP首部),除后一个分片外,其它分片数据长度为8字节的倍数;
2)除复制对应数据外,还复制原始分组的首部及(部分)选项到新的每个分片中,更新新分片首部的头部长度、总长度、MF标志和偏移量。如果原始分组已经是分片,那么MF=1,否则最后一个分片MF=0,其余MF=1。

3. 何时何地重装?
由于分片可以有不同的路由,而且中途路由器可能再次分片,因此只有目标主机才能重装所有分片。当接收端第一次收到一个MF或偏移量非零的分组时,则该分组就是一个必须被重装的分片,于是开始重装。

4. 如何重装?
1)使用4元组{源地址,目标地址,协议,16位标识}为唯一标识查找当前分片所属的数据报(分片表),如果没有找到,则创建分片表,按偏移量将当前分片插入到分片表,并启动重装定时器;
2)如果重装定时器超时后,还没有组装好一个完整的IP数据报,此时如果已经收到第一个分片,则向源主机返回ICMP超时差错,最后丢弃收到的所有分片;否则,提交数据给适当的传输层处理。

5. 哪些分组能被转发,何时转发?
到达非最终目的地系统的分组,且当系统配置为可转发或分组包含源路由时,才能被转发,但下列类型的分组除外:1)链路层广播 2)环回分组 3)网络0和E类目标地址 4)D类目标地址。

【ICMP】
1. ICMP报文有哪些类型,何时何地生成这些报文?
包括请求、应答、差错和重定向4种,其中前两者可统一为查询类。请求当需要查询的时候由进程生成,应答由当内核收到请求报文时生成,当主机发出的数据报无法成功地提交给目的主机时,目的主机或中间路由器的IP或传输协议生成差错报文,并返回给原来的系统。

2. 内核怎么处理收到的ICMP报文?
ICMP是一种传输层协议,其协议号为1,当IP层收到一个ICMP报文时,分用交给ICMP协议输入处理,ICMP协议输入根据其类型分别处理:
1)请求---生成适当的应答报文
2)差错---提交给适当的传输层协议处理
3)应答---提交给等待ICMP报文的进程
4)重定向---更新路由表,并提交给等待的进程。

3. 怎么发送ICMP报文?
构造ICMP报文-->计算ICMP检验和-->封装到IP数据报中-->提交给IP协议输出处理,对于用户进程,须使用原始IP机制才能发送。

4. 哪些情况不会产生ICMP差错报文,为什么?
1)ICMP差错报文:违反此条可能导致差错引起差错,无休止循环下去;
2)源地址不是单播地址的IP数据报:违反此条导致差错可能同时发到多个主机;
3)目的地址是广播或多播地址的IP数据报:违反此条导致多个主机可能同时响应;
4)作为链路层广播的数据报:违反此条导致多个主机可能同时响应;
5)不是IP分片的第一片:违反此条可能导致产生多个ICMP差错,每个分片一个。

由此可见,违反以上几条都会引起网络风暴。

【TCP & UDP】
1. 为什么TCP首部存在首部长度字段,而UDP却没有?
TCP首部存在选项,如mss,timestame,nop和wscale等。

2. 为什么这两种协议首部前面都是源和目的端口?
当TCP收到一个ICMP差错时,必须检查两个端口号以决定差错对应于哪个连接;只有当UDP套接口连接到对端时,用户进程才会收到ICMP差错,例如当服务器未运行时,返回的ICMP端口不可达消息。

3. 当收到TCP或UDP数据包时,怎么提交给应用层?
插口由进程调用socket或accept创建,关联到对应的PCB(协议控制块)上,通配匹配数由本地和外部IP地址确定,有3种取值:0--本地和外部IP都不为*、1--本地或外部IP有一个为*和2--本地和外部IP都为*。与UDP不同的是,TCP还有自己的PCB。
1)TCP:先扫描Internet PCB,查找最小通配匹配数的插口,如果没找到,那么响应RST包;再查看对应的TCP PCB,若不存在则响应RST包,否则若TCP 状态为关闭,则丢弃;最后交付给找到的对应插口。
2)UDP:这里要分2种情况,对于目的地为广播或多播地址的IP数据报,交付给所有匹配的插口;对于目的地为单播的IP数据报,扫描Internet PCB,查找具有最小通配匹配数的插口,如果没有找到,则向源主机发送ICMP端口不可达差错。如果有多个插口有相同的最小通配匹配数,那么具体由哪个插口接收依赖于不同的实现。

4. 计算首部检验和时,为什么要引入伪首部?
这是因为考虑到IP层的可能差错,TCP和UDP需要验证数据包是否被递送到正确的协议和目的主机。

5. UDP何时会计算检验和,如何区分是否使用了检验和?
UDP的检验和是可选的,当系统没有禁止(udpcksum非零)时,发送方会计算检验和,接收方还须输入分组检验和非零时才会计算检验和。如果检验和字段非零,那么就使用了,反之没有。

6. 在TCP状态迁移中,哪些状态在什么情况下可直接转到CLOSED状态?
SYN_SENT在连接定时器超时后,FIN_WAIT_2在FIN_WAIT_2定时器超时后。

7. 为什么TCP需要持续(persist)定时器、FIN_WAIT_2定时器和2MSL定时器?
1)因为连接对端发送的窗口通告为ACK报文,而ACK是不会确认的,允许TCP继续发送数据的窗口更新可能会丢失,所以需要设定persist定时器,在超时后发送1字节的数据,判定对端接收窗口是否已打开;
2)因为在正常情况下,当连接主动关闭时,会由FIN_WAIT_1状态进入FIN_WAIT_2状态等待接收对端的FIN报文,但对方可能一直不发送FIN,所以需要FIN_WAIT_2定时器避免连接永远滞留在FIN_WAI_2状态;
3)因为当连接主动关闭进入TIME_WAIT状态后,将等待2个MSL时间,在这段时间内,TCP可以重发丢失的ACK,丢弃来自新连接替身的迟到的报文段以防止被曲解,所以需要2MSL定时器,超时后关闭连接。

8. 当TCP发送数据,调用ip_output返回ENOBUFS差错时,可能会发生什么情况?
当提交给网络层因为内存不足发送失败时,数据包被丢弃。如果丢弃的是数据报文,重传定时器超时后数据将被重传;如果丢弃的是纯ACK报文,对端收不到ACK时会重传对应的数据报文;如果丢弃的是RST报文,当对端重传导致发送RST报文的数据报文时,将再次生成RST报文。

9. TCP何时发送ACK报文?
对于数据、SYN和FIN报文,发送ACK,但对于纯ACK和RST报文,不会发送;另外当遇以下情况时,则立即发送。
1)200ms延时ACK定时器超时;
2)收到失序的报文段;
3)三次握手收到了SYN;
4)收到了FIN。

10. TCP何时发送RST报文?
1)当收到报文段,但没有找到对应的internet pcb或tcp pcb。
2)当连接处于LISTEN状态时,收到了ACK报文段。
3)当连接处于SYS_SENT状态时,收到了错误的ACK报文段(ack小于等于iss或大于snd_max)。
4)当连接被动关闭时(状态大于CLOSE_WAIT),收到了数据。
5)当连接处于SYN_RCVD状态时,收到了错误的ACK报文段(ack小于snd_una或大于snd_max)。

【Domain & Protocol】
1. 什么是域,它和协议有什么关系?
域可以理解为一种容纳协议的空间,它的存在便于了协议的分类;域和协议是集合与元素的关系,一个域中的每个协议使用同类地址,并且每种地址只被一个域使用,一个域能由协议族或地址族常量唯一标识。

2. TCP/IP中有哪些域及其协议?
internet、iso、route、ccitt、imp、network systems和unix,其中internet域含有ip,icmp,igmp,tcp和udp五种协议,unix域用于ipc通信。

3. 哪些地方会用到域?
一个网络层协议必须分用输入数据报,并交给相应的传输层协议,由于域包含了协议族,因此必须从对应的域中找到合适的协议去处理。例如IP对应的域为internet,这个域对应的协议族为inetsw,当收到IP数据报时,就从inetsw中找到对应的传输层协议去输入处理。

【IP Addressing】
1. IP地址有哪几类?
分为5类,A、B和C类用于单播;D类用于多播;E类用于实验。

2. sockaddr和sockaddr_in有什么区别联系?
sockaddr是一种通用的用于接口编址信息的结构,它将硬件与协议的地址细节相对于接口层隐藏起来,成员依次为sa_len、sa_family和sa_data,而sockaddr_in成员依次为sin_len、sin_family、sin_port、sin_addr和sin_zero。它们的前两个成员其实是一样的,只是命名不同,而sockaddr_in中的sin_port标识传输层的端口,sin_addr标识IP层的地址,所以它是Internet协议的专用接口编址结构,sin_zero仅为填充用,因为sockaddr_in长度不应小于sockaddr。

3. 插口编址结构允许的最大长度是多少?
sockaddr最后一个成员是可扩展的,这是C语言的通用技术,因为其第一个成员为u_char类型,所以最大长度是255。

4. 一个接口可以配置多个IP地址,是怎么实现的?
ifaddr表示通用的接口地址,ifnet表示接口,它有个类型为ifaddr*的if_addrlist成员,表示当前接口上的地址链表。in_ifaddr表示Internet协议专用的接口地址,而IP属于Internet协议,因此用in_ifaddr表示,所有的IP地址组成一个类型为in_ifaddr*的链表。当增加一个IP地址时,就需要插入这两个链表中;当删除一个IP地址时,就需要从它们当中移除。

5. 为什么配置IP主机地址和网络掩码可以是独立的?
因为它们使用不同的命令实现,前者用SIOCSIFADDR,后者用SIOCSIFNETMASK。当配置IP主机地址时,如果没有指明网络掩码,那么网络掩码被设置成默认的。

6. 为什么访问IP接口地址使用的是UDP插口而不是原始IP插口?
只有超级用户用程才能创建原始IP插口,而通过UDP插口,任何用户进程都能查看接口配置。

【Socket】
1. 为什么会存在插口层?
从概念上讲,tcp/ip协议栈划分为链路、网络、传输和应用4层;但从实现上讲,在应用层和其下层中间,引入了一个插口层,作为进程和内核通信的桥梁,主要功能是将进程发送的与协议有关的请求映射到产生插口时指定的与协议有关的实现,从而屏蔽了不同协议处理的细节。

2. 为什么服务器进程总是要调用bind,客户进程能调用它吗?
bind将一个本地地址同一个插口相关联,客户进程需要同一个已知地址建立连接或发送数据报到已知地址,如果不调用bind,服务器进程就无法在某个已知地址上接受TCP连接或接收UDP数据报。客户进程也能调用bind,这样便可以由应用程序而非内核来选择一个本地地址,其结果是只能接收目的地址为被绑定地址的数据包,但通常不必调用bind,因为内核会自动决定外出地址和临时端口。

3. 对于tcp和udp协议的插口,调用connect有什么区别联系?
共同点是设定插口的外部地址(插口的地址存储在相关的协议控制块中),不同点如下:
1)tcp:与远端系统进行3次握手交互,如果插口是非阻塞的且连接正在进行中,那么返回EINPROGRESS,下次再调用则返回EALREADY;如果连接成功,无论是否阻塞,那么下次再调用会返回EISCONN;如果连接失败,那么下次再调用,则重新开始三次握手;
2)udp:没有3次握手交互,直接设定外部地址,无论插口是否阻塞,调用会立即返回,多次调用则会替换老的外部地址。发送数据必须使用write或目的地址为空的sendto,若sendto目的地址非空,则返回EISCONN。如果没有事先调用connect,那么调用目的地址为空的sendto则会返回ENOTCONN。

4. 什么情况下调用close会阻塞?
连接已建立且设置了SO_LINGER选项并延时值非零的阻塞插口。

5. 插口IO有哪些系统调用?
发送有write、writev、sendto和sendmsg,接收有read、readv、recvfrom和recvmsg。注意,send和recv是库函数而非系统调用,前者调用sendto实现,后者调用recvfrom实现。

6. write、writev、read、readv与sendto、sendmsg、recvfrom、recvmsg有什么不同?
1)前面4个适合于任何描述符,而后面4个只能用于插口;
2)前面4个不支持标志,而后面4个支持;
3)前面前2个不支持目的地址、后2个不支持源地址,而后面前2个支持目的地址、后2个支持源地址;
4)前面4个不支持控制信息,而后面第2个和第4个支持。

7. 如何断开已连接的udp插口,允许调用sendto向其它主机发送数据?
由于系统并没有提供形如disconnect的断连API,但connect内部实现是先断连,再调用对应协议的PRU_CONNECT请求处理,因此向connect传递无效的外部地址结构(如IP=0.0.0.0,Port=0),虽然这样会导致结果失败,但先前的断连成功,对应pcb的外部地址被设为INADDR_ANY,所以调用sendto就不会返回EISCONN。

【Raw IP】
1. 怎么使用原始IP,它有哪些用途及应用?
创建SOCK_RAW类型的原始插口,就能使用原始IP机制,它有下列用途:
1)发送和接收ICMP和IGMP报文,如ping程序和多播路由守护程序;
2)构造自己的IP首部,如路由跟踪程序;
3)设计基于IP的新的传输层协议,如gated程序。

2. 协议值为PROTOCOL_RAW(255)的原始插口能收到什么类型的IP数据报?
由于255是非零的保留值,这样的IP数据报在网络中不会存在,原始IP输入处理协议比较测试失败,因此收不到任何类型的IP数据报。

3. 协议值为0的原始插口能收到什么类型的IP数据报?
由于协议值为0,原始IP输入处理忽略了协议比较测试,因此能收到任何类型的IP数据报。

4. 如何处理收到的IP数据报?
遍历Internet PCB表,依次从协议值、本地地址和外部地址三项来比较IP数据报和每个PCB,将IP数据报复制追加到所有匹配的PCB对应的插口缓存中,并唤醒等待的进程。

5. 如何发送数据?
先填充IP首部,如果未设置IP_HDRINCL选项,那么由内核填充,否则由应用程序在发送前填充,再交给IP协议输出处理。

6. 内核何时会调用原始输入?
当收到的协议类型为除IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP和IPPROTO_IGMP外的IP数据报时调用。

【Unix domain】
1. 使用unix域的原因有哪些?
1)当通信双方在同一主机上时,使用unix域插口的速度比tcp和udp插口要快很多;
2)支持同一主机进程间传递描述符。

2. unix域和internet域有什么不同?
1)编址结构不同:前者是sockaddr_un,与文件系统路径名关联,而后者是sockaddr_in,与IP地址和端口关联;
2)协议控制块不同:前者是unpcb,没有全局的pcb链表,而后者是inpcb,有全局的pcb双向循环链表。

3. 如果一个unix域服务器在bind后unlink了被绑定的路径名,会发生什么情况?
因为connect内部实现查找路径名失败,所以连接失败,但listen会成功,因为bind会创建新的vnode和pcb关联,且PRU_LISTEN请求实现只检查vnode是否为空。

4. 如果一个unix域服务器在终止时没有unlink被绑定的路径名,会发生什么情况?
因为connect内部实现虽能找到路径名但找不到相关的插口,所以连接被拒绝。

5. 系统调用socketpair和pipe有什么区别联系?
共同点是使用unix域,即socket调用第1参数为AF_UNIX,不同点如下
1)前者是双工的,因为两个插口标志都为读写,且它们的pcb相互指向对方;后者是单工的,因为一个插口标志为只读,另一个为只写,写插口的pcb指向读插口的pcb;
2)前者支持数据报和流式插口,后者仅支持流式插口。

6. unix域是怎么实现传递描述符的?
描述符存储在控制信息cmsghdr内,cms_level=SOL_SOCKET且cms_type=SCM_RIGHTS,unix域的发送请求实现将描述符转换为file指针,这个过程叫内部化,接收请求实现把file指针转换为最小的没有使用的描述符,这个过程叫外部化。

10 Differences between TCP and UDP

TCP vs UDP – Acronym

1.TCP: Transmission Control Protocol

2.UDP: User Datagram Protocol

TCP vs UDP – Connection

1.TCP: Is a connection-oriented protocol. This means the system is able to send and receive data.

2.UDP: Is a connection-less protocol. This means the service can only send packets.

TCP vs UDP – Protocols

1.TCP: HTTP, HTTPs, FTP, SMTP, Telnet

2.UDP: DNS, DHCP, TFTP, SNMP, RIP, VOIP.

TCP vs UDP – Packet Order

Packets are carried over Internet Protocol (IP), which pays no attention to packet order.

1.TCP: Orders the data to be streamed linearly, however, this does not ensure the packets will be received in an ordered fashion. TCP combats this by assigning the data a sequence of numbers, so that as they arrive they may be rearranged or requested if not received.

2.UDP: Has no inherent order as all packets are independent of each other. UDP is used when data transmission speed is preferred over packet loss. If ordering is required, it has to be managed by the application layer.


TCP vs UDP – Transmission speed

1.TCP: Is slower than UDP, because it requires acknowledgment of packets. However, TCP does provide congestion control, while UDP does not. TCP is smart enough to detect the available bandwidth and moderate packages based on that metric.

2.UDP: Is typically the fastest, because is does not require package acknowledgement and can establish a continuous packet stream. Although, if you have a lot of a packets being pushed out at one time they will all compete for the most bandwidth and put a heavy load the system.

 
TCP vs UDP – Reliability

1.TCP: Checks to see if all transmitted data was received, and if not it can recover of segments that get lost, damaged, duplicated or received out of their correct order.

2.UDP: There is no guarantee that the messages or packets sent will received at all. Packets are sent individually and are checked for integrity only if they arrive. Packets have definite boundaries which are honored upon receipt, meaning a read operation at the receiver socket will yield an entire message as it was originally sent.

TCP vs UDP – Load

1.TCP: High network load. TCP requires three packets to set up a socket connection, before any user data can be sent. TCP handles reliability and congestion control.

2.UDP: Is lightweight. There is no ordering of messages, no connections monitoring, and no integrity checking.

TCP vs UDP – Data Flow Control

1.TCP: Moderate network load. TCP requires three packets to set up a socket connection, before any user data can be sent. TCP handles reliability and congestion control. Because a TCP connection is bidirectional (can send and receive messages), each direction will have to be terminated independently.

2.UDP: Sends the packets as fast as possible and, therefore, does not avoid congestion. Congestion control measures must be implemented at the application level.

TCP vs UDP – Troubleshooting Capabilities

1.TCP: Performs error checking and error recovery. Corrupted packets are re-transmitted from the source to the destination. Error recovery is possible.

2.UDP: Does error checking only when received, and but simply discards corrupt packets. Error recovery is not possible.

TCP vs UDP – Fields

1.TCP: 1. Sequence Number, 2. AcK number, 3. Data offset, 4. Reserved, 5. Control bit, 6. Window, 7. Urgent Pointer 8. Options, 9. Padding, 10. Check Sum, 11. Source port, 12. Destination port

2.UDP: 1. Length, 2. Source port, 3. Destination port, 4. Check Sum

TCP vs UDP – Handshake

1.TCP: SYN, SYN-ACK, ACK

2.UDP: No handshake (connectionless protocol)


SCTP

SCTP(Stream Control Transmission Protocol,流控制传输协议)是IETF(Internet Engineering Task Force,因特网工程任务组)在2000年定义的一个传输层(Transport Layer)协议,是提供基于不可靠传输业务的协议之上的可靠的数据报传输协议。

SCTP的设计用于通过IP网传输SCN(Signaling Communication Network,信令通信网)窄带信令消息。后期广泛用于EPC网络中的S6a/S1/Sgs/Sv等接口中。SCTP是一个面向连接的流传输协议,它可以在两个端点之间提供稳定、有序的数据传递服务。SCTP可以看做是TCP协议的改进,它继承了TCP较为完善的拥塞控制并改进TCP的一些不足之处:
(1)SCTP与TCP的最大不同之处在于它是多宿主(Multi-homing)连接,而TCP是单地址连接。

(2)一个TCP连接只能支持一个流,一个SCTP连接可以支持多个流(Multi-streaming)。在SCTP协议中,流(Stream)是指从一个SCTP端点到另一端点之间建立的单向逻辑通路,通常情况下所有用户消息在流中按序传递。

(3) SCTP有更好的安全性。SCTP实际上是一个面向连接的协议,但SCTP偶联的概念要比TCP的连接具有更广的概念,SCTP对TCP的缺陷进行了一些完善,使得信令传输具有更高的可靠性,SCTP的设计包括适当的拥塞控制、防止泛滥和伪装攻击、更优的实时性能和多归属性支持。

(4)SCTP最初是被设计用于在IP上传输电话,把SS7(Signaling System No. 7,七号信令系统)信令网络的一些可靠特性引入IP。IETF的这方面的工作称为信令传输SIGTRAN。在此期间,也提出了这个协议的其他一些用途。

SCTP提供如下服务:
确认用户数据的无错误和无复制传输;
数据分段以符合发现路径最大传输单元的大小;
在多数据流中用户信息的有序发送,带有一个选项,用户信息可以按到达顺序发送;
选择性的将多个用户信息绑定到单个SCTP包;
通过关联的一个终端或两个终端多重宿主支持来为网络故障规定容度。

关系:

作为一个传输层协议,SCTP兼有TCP及UDP两者的特点。SCTP可以称为是TCP的改进协议,但它们之间仍然存在着较大的差别。

(1)首先SCTP和TCP之间的最大区别是SCTP的连接可以是多宿主连接的,TCP则一般是单地址连接的。在进行SCTP建立连接时,双方均可声明若干IP地址(IPv4,IPv6或主机名)通知对方本端所有的地址。若当前连接失效,则可切换到另一个地址,而不需要重新建立连接。

(2)其次SCTP是基于消息流,而TCP则是基于字节流。所谓基于消息流,是指发送数据和应答数据的最小单位是消息包(chunk)。一个SCTP连接(Association)同时可以支持多个流(stream),每个流包含一系列用户所需的消息数据(chunk)。而TCP则只能支持一个流。

(3)在网络安全方面,SCTP增加了防止恶意攻击的措施。不同于TCP连接采用的三次握手机制,SCTP连接采用四次握手机制,有效的防止了类似于SYN Flooding的防范拒绝服务攻击。SCTP主要的贡献是对多重联外线路的支持,一个端点可以由多于一个IP地址组成,使得传输可在主机间或网卡间做到透明的网络容错备援。

SCTP功能:SCTP 的功能主要包括:偶联的建立和关闭、流内消息顺序递交、用户数据分段、证实和避免拥塞、消息块绑定、分组的有效性和通路管理。

SCTP 功能示意图


1、偶联的建立和关闭
偶联的建立是由 SCTP 用户(如M2UA、M3UA 等)发起请求来启动的。而且建立过程相对于TCP连接而言比较复杂,是个“四次握手”过程,并用到了“COOKIE” 的机制。

COOKIE 是一个含有端点初始信息和加密信息的数据块,通信的双方在关 联建立时需要处理并交换,从而增加协议的安全性,防止拒绝服务和伪装等潜在的攻击。SCTP 提供了对激活偶联的正常的关闭程序,它必须根据SCTP用户的请求来执行,当然SCTP也提供一种非正常(即中止)程序,中止程序的执行既可以根据SCTP用户的请求来启动,也可以由SCTP协议检查出差错来中止。 SCTP 不支持半打开状态(即一端可以在另一端结束后继续发送数据)。无论是哪个端点执行了关闭程序,偶联的两端都应停止接受从SCTP用户发来请求原语。

2、流内消息顺序递交
SCTP 提供数据报的顺序传递,顺序传递的数据报必须放在一个“流”中传递。流 是顺序传递的基石。通过流,SCTP 将数据的确认和传输的有序递交分成两种不同机制。SCTP 使用TSN 机制实现了数据的确认传输,使用流号和SSN(流顺序号)则实现数据的有序递交。当SCTP 收到数据的SSN 连续的时候,SCTP 就可以将数据向SCTP 用户递交,而不用等到数据的TSN 号连续以后才向SCTP 用户递交。

当一个流被闭塞时,期望的下一个连续的SCTP 用户消息可以从另外的流上进行递 交。 SCTP 也提供非顺序递交的业务,接收到的用户消息可以使用这种方式立即递交到 SCTP 用户,而不需要保证其接收顺序。

3、用户数据分段
SCTP 通过对传送通路上最大PMTU(Path Maximum TransmissiON Unit)的检测, 实现在SCTP 层将超大用户数据分片打包,避免在IP 层的多次分片、重组,可以减 少IP 层的数据负担。

在发送端,SCTP 可以对大的用户数据报进行分片以确保SCTP 数据报传递到低层时适合通路MTU(Maximum Transmission Unit)。

在接收端,SCTP 将分片重组为完整的用户数据报,然后传递给SCTP 用户。

4、证实和避免拥塞
证实和重传是协议保证传输可靠性的策略,SCTP 也一样。证实机制是SCTP 保证 传输可靠性的基石。避免拥塞沿袭了TCP 的窗口机制,进行合适的流量控制。

SCTP 在将数据(数据分片或未分片的用户数据报)发送给底层之前顺序地为 之分配一个发送顺序号(TSN)。

TSN 和SSN(流顺序号)是相互独立的,TSN 用于保证传输的可靠性,SSN 用于保证流内消息的顺序传递。

TSN 和SSN 在功能上使可靠传递和顺序传递分开。接收端证实所有收到的 TSNs,即使其中有些尚未收到。

包重发功能负责 TSN 的证实,还负责拥塞消除。

5、消息块绑定
如果长度很短的用户数据被带上很大一个 SCTP 消息头,其传递效率会很低,因此, SCTP 将几个用户数据绑定在一个SCTP 报文里面传输,以提高带宽的利用率。

SCTP 分组由公共分组头和一个/多个信息块组成,信息块可以是用户数据,也 可以是SCTP 控制信息。

SCTP 用户能够可选地使用捆绑功能,决定是否将多个用户数据报捆绑在一个 SCTP 分组中。

为提高效率,拥塞/重发时,捆绑功能可能仍被执行,即使用户已经禁止捆绑。

6、分组的有效性
分组的有效性是 SCTP 提供无差错传输的基石。SCTP 分组的公共分组头包含一个 验证标签(VerificATIon Tag)和一个可选的32 位校验码(Checksum)。验证标签的值由偶联两端在偶联启动时选择。如果收到的分组中如果没有期望的验 证标签值,接收端将丢弃这个分组,以阻止攻击和失效的SCTP 分组。 校验码由 SCTP 分组的发送方设置,以提供附加的保护,用来避免由网络造成的数 据差错。接收端将丢弃包含无效校验码的SCTP 分组。

7、通路管理
发送端的 SCTP 用户能够使用一组传送地址作为SCTP 分组的目的地。SCTP 管理 功能可以根据SCTP 用户的指令和当前合格的目的地集合的可达性状态,为每个发 送的SCTP 分组选择一个目的地传送地址。当其他分组业务量不能完全表明可达性时,通路管理功能可以通过心跳消息来监视到某个目的地地址的可达性,并当任何对端传送地址的可达性发生变化时,向SCTP 用户提供指示。通路功能也用来在偶 联建立时,向对端报告合格的本端传送地址集合,并把从对端返回的传送地址报告 给本地的SCTP 用户。在偶联建立时,为每个 SCTP 端点定义一个首选通路,用来正常情况下发送SCTP 分组。

在接收端,通路管理功能在处理SCTP 分组前,用来验证入局的SCTP 分组属于的偶联是否存在。