TCP/IP四层模型
ISO制定的OSI参考模型的过于庞大、复杂招致了许多批评。与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用。 如图所示,是TCP/IP参考模型和OSI参考模型的对比示意图。在TCP/IP参考模型中,去掉了OSI参考模型中的会话层和表示层(这两层的功能被合并到应用层实现)。同时将OSI参考模型中的数据链路层和物理层合并为主机到网络层。下面,分别介绍各层的主要功能。实际上TCP/IP参考模型没有真正描述这一层的实现,只是要求能够提供给其上层-网络互连层一个访问接口,以便在其上传递IP分组。由于这一层次未被定义,所以其具体的实现方法将随着网络类型的不同而不同。网络互连层是整个TCP/IP协议栈的核心。它的功能是把分组发往目标网络或主机。同时,为了尽快地发送分组,可能需要沿不同的路径同时进行分组传递。因此,分组到达的顺序和发送的顺序可能不同,这就需要上层必须对分组进行排序。网络互连层定义了分组格式和协议,即IP协议(Internet Protocol)。网络互连层除了需要完成路由的功能外,也可以完成将不同类型的网络(异构网)互连的任务。除此之外,网络互连层还需要完成拥塞控制的功能。在TCP/IP模型中,传输层的功能是使源端主机和目标端主机上的对等实体可以进行会话。在传输层定义了两种服务质量不同的协议。即:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。TCP协议是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。在接收端,它负责把收到的报文进行重组后递交给上层。TCP协议还要处理端到端的流量控制,以避免缓慢接收的接收方没有足够的缓冲区接收发送方发送的大量数据。UDP协议是一个不可靠的、无连接的协议,主要适用于不需要对报文进行排序和流量控制的场合。TCP/IP模型将OSI参考模型中的会话层和表示层的功能合并到应用层实现。应用层面向不同的网络应用引入了不同的应用层协议。其中,有基于TCP协议的,如文件传输协议(File Transfer Protocol,FTP)、虚拟终端协议(TELNET)、超文本链接协议(Hyper Text Transfer Protocol,HTTP),也有基于UDP协议的。IP协议是TCP/IP协议族中最为核心的协议。它提供不可靠、无连接的服务,也即依赖其他层的协议进行差错控制。在局域网环境,IP协议往往被封装在以太网帧中传送。而所有的TCP、UDP、ICMP、IGMP数据都被封装在IP数据报中传送。IP报文格式:IP头部格式:其中:● 版本(Version)字段:占4比特。用来表明IP协议实现的版本号,当前一般为IPv4,即0100。● 报头长度(Internet Header Length,IHL)字段:占4比特。是头部占32比特的数字,包括可选项。普通IP数据报(没有任何选项),该字段的值是5,即160比特=20字节。此字段最大值为60字节。● 服务类型(Type of Service ,TOS)字段:占8比特。其中前3比特为优先权子字段(Precedence,现已被忽略)。第8比特保留未用。第4至第7比特分别代表延迟、吞吐量、可靠性和花费。当它们取值为1时分别代表要求最小时延、最大吞吐量、最高可靠性和最小费用。这4比特的服务类型中只能置其中1比特为1。可以全为0,若全为0则表示一般服务。● 总长度字段:占16比特。指明整个数据报的长度(以字节为单位)。最大长度为65535字节。● 标志字段:占16比特。用来唯一地标识主机发送的每一份数据报。通常每发一份报文,它的值会加1。● 标志位字段:占3比特。标志一份数据报是否要求分段。● 段偏移字段:占13比特。如果一份数据报要求分段的话,此字段指明该段偏移距原始数据报开始的位置。● 生存期(TTL:Time to Live)字段:占8比特。用来设置数据报最多可以经过的路由器数。由发送数据的源主机设置,通常为32、64、128等。每经过一个路由器,其值减1,直到0时该数据报被丢弃。● 协议字段:占8比特。指明IP层所封装的上层协议类型,如ICMP(1)、IGMP(2) 、TCP(6)、UDP(17)等。● 头部校验和字段:占16比特。内容是根据IP头部计算得到的校验和码。计算方法是:对头部中每个16比特进行二进制反码求和。(和ICMP、IGMP、TCP、UDP不同,IP不对头部后的数据进行校验)。● 源IP地址、目标IP地址字段:各占32比特。用来标明发送IP数据报文的源主机地址和接收IP报文的目标主机地址。可选项字段:占32比特。用来定义一些任选项:如记录路径、时间戳等。这些选项很少被使用,同时并不是所有主机和路由器都支持这些选项。可选项字段的长度必须是32比特的整数倍,如果不足,必须填充0以达到此长度要求。TCP是一种可靠的、面向连接的字节流服务。源主机在传送数据前需要先和目标主机建立连接。然后,在此连接上,被编号的数据段按序收发。同时,要求对每个数据段进行确认,保证了可靠性。如果在指定的时间内没有收到目标主机对所发数据段的确认,源主机将再次发送该数据段。 TCP是一种可靠的、面向连接的字节流服务。源主机在传送数据前需要先和目标主机建立连接。然后,在此连接上,被编号的数据段按序收发。同时,要求对每个数据段进行确认,保证了可靠性。如果在指定的时间内没有收到目标主机对所发数据段的确认,源主机将再次发送该数据段。TCP头部结构:其中:● 源、目标端口号字段:占16比特。TCP协议通过使用"端口"来标识源端和目标端的应用进程。端口号可以使用0到65535之间的任何数字。● 顺序号字段:占32比特。用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段中的第一个数据字节。● 确认号字段:占32比特。只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。● 头部长度字段:占4比特。给出头部占32比特的数目。没有任何选项字段的TCP头部长度为20字节;最多可以有60字节的TCP头部。● 标志位字段(U、A、P、R、S、F):占6比特。各比特的含义如下:◆ URG:紧急指针(urgent pointer)有效。◆ ACK:确认序号有效。◆ PSH:接收方应该尽快将这个报文段交给应用层。◆ RST:重建连接。◆ SYN:发起一个连接。◆ FIN:释放一个连接。● 窗口大小字段:占16比特。此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。● TCP校验和字段:占16比特。对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,并由目标端进行验证。● 紧急指针字段:占16比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。● 选项字段:占32比特。可能包括"窗口扩大因子"、"时间戳"等选项。UDP是一种不可靠的、无连接的数据报服务。源主机在传送数据前不需要和目标主机建立连接。数据被冠以源、目标端口号等UDP报头字段后直接发往目的主机。这时,每个数据段的可靠性依靠上层协议来保证。在传送数据较少、较小的情况下,UDP比TCP更加高效。UDP头部结构:● 源、目标端口号字段:占16比特。作用与TCP数据段中的端口号字段相同,用来标识源端和目标端的应用进程。● 长度字段:占16比特。标明UDP头部和UDP数据的总长度字节。● 校验和字段:占16比特。用来对UDP头部和UDP数据进行校验。和TCP不同的是,对UDP来说,此字段是可选项,而TCP数据段中的校验和字段是必须项。在每个TCP、UDP数据段中都包含源端口和目标端口字段。有时,我们把一个IP地址和一个端口号合称为一个套接字(Socket),而一个套接字对(Socket pair)可以唯一地确定互连网络中每个TCP连接的双方(客户IP地址、客户端口号、服务器IP地址、服务器端口号)。如图所示,是常见的一些协议和它们对应的服务端口号。需要注意的是,不同的应用层协议可能基于不同的传输层协议,如FTP、TELNET、SMTP协议基于可靠的TCP协议。TFTP、SNMP、RIP基于不可靠的UDP协议。同时,有些应用层协议占用了两个不同的端口号,如FTP的20、21端口,SNMP的161、162端口。这些应用层协议在不同的端口提供不同的功能。如FTP的21端口用来侦听用户的连接请求,而20端口用来传送用户的文件数据。再如,SNMP的161端口用于SNMP管理进程获取SNMP代理的数据,而162端口用于SNMP代理主动向SNMP管理进程发送数据。还有一些协议使用了传输层的不同协议提供的服务。如DNS协议同时使用了TCP 53端口和UDP 53端口。DNS协议在UDP的53端口提供域名解析服务,在TCP的53端口提供DNS区域文件传输服务。 来自陈十一

TCP-IP详解卷1:协议读书笔记_2
在TCP/IP协议族中,链路层主要有三个目的: (1)为IP模块发送和接受IP数据报(2)为ARP模块发送ARP请求和接受ARP应答(3)为RARP发送RARP请求和接收RARP应答以太网是当今TCP/IP采用的主要的局域网技术。它采用一种称作CSMA/CD的额媒体接入方法,其意思是带冲突检测的载波侦听多路接入。它的速率为10MB/S,地址为48bit。主机需求RFC要求每个Internet主机都与10MB/s的以太网电缆相连接:1)必须能发送和接受采用RFC894(以太网)封装格式的分组2)应该能接受与RFC894混合的RFC1024(IEEE082)封装格式的分组3)也许能够发送采用RFC1024格式封装的分组最常使用的封装格式是RFC 894定义的格式。下图显示了两种形式的封装格式。图中每个方框下面的数字是它们的字节长度。两种帧格式都采用48bit(6字节)的目的地址和源地址。ARP和RARP协议对32位bit的IP地址和48bit的硬件地址进行映射。接下来两个字节在两种帧格式中互不相同。RFC1024定义的长度字段是指它后续数据的字节长度,但不包括CRC校验码。RFC894定义了后续数据的类型。RFC1024的有效长度和RFC894有效类型值都不相同,所以,可以对两种帧格式进行区分。RFC894类型后面就是数据;而RFC1024后有哦3个字节的802.2LLC和5个字节的802.2SNAP。目的服务访问点和源服务访问点的值都设为0Xaa。Ctrl字段的值设为3。随后的3个字节org code都置为0。再接下来两个字节类型和以太网格式一样。CRC字段用于帧内后续字节差错的循环冗余码检验。RFC893描述了另一种用于以太网的封装格式,称作尾部封装。在以太网数据帧中,开始的那部分是边长的字段;将其移动到尾部(CRC之前),这样将数据复制到内核时,就可以把数据帧的数据部分映射到一个硬件页面,节省内存到内存的赋值过程SLIP全称是Serial Line IP。它是一种在串行线路行对IP数据报进行封装的简单形式。SLIP适用于家庭中每台计算机几乎都有的RS-232串行端口和高速调制解调器接入Internet。下面的规则描述了SLIP协议定义的帧格式:1)IP数据报以一个END(0xc0)的特殊字符结束。同时,为了防止数据报到来之前的线路噪声也被当成数据报内容,大多数实现在数据报的开始处也传一个END字符。2)如果IP数据报的某个数据是END,那么就要联系传输两个字节0xdb和0Xdc来取代它。0xdb称为SLIP的ESC字符,但是它的值和ASCII码的ESC字符0x1b不同。3)如果IP报文中某个字符为SLIP的ESC字符,那么就要连续传输两个0xdb和0xdd来取代它。SLIP的图示:SLIP的缺陷:1)每一段必须知道对方的IP地址,没有办法把本端的IP地址通知给另一端。2)数据帧中没有类型字段。如果一条串行线路用于SLIP,那么它不能同时使用其他协议。3)SLIP没有在数据帧中加上校验和。SLIP线路行有许多小的TCP分组进行交换。为了传送1个字节的数据需要20个字节的IP首部和20个字节的TCP首部,总数超过40个字节。于是有了CSLIP的新协议,即压缩SLIP。一般可以把上面40个字节压缩到3-5个字节。PPP点对点协议,包含了一下三个部分:1)在串行链路上封装IP数据报的方法。PPP既支持数据为8位的无奇偶校验的异步模式,还支持面向比特的同步链接。2)建立、配置以及测试数据链路的链路控制协议(LCP)。它允许通信双发进行协商,以确定不同的选项。3)针对不同网络层协议的网络控制协议体系。PPP数据帧都是以标志字符0x7e开始和结束。紧接着是一个地址字节,值始终为0x03的字节字符。接下来是协议字段,类似于以太网中类型字段的功能。0X0021代表IP数据报;0XV021代表链路控制数据;0x8021代表信息是网络控制数据。CRC字段,是一个循环冗余校验码,以检测数据帧中的错误。总的来说,PPP比SLIP具有以下优点:1.PPP支持单根串行线路上运行多种协议;2.每一帧都有循环冗余校验;3.通信双方可以进行IP地质的动态协商(使用IP网络控制协议);4.与CSLIP类似,对TCP和IP报文首部进行压缩;5.链路控制协议可以对多个数据链路选项进行设置。大多数产品都支持环回接口,以允许运行在同一主机上的客户程序和服务器程序通过TCP/IP进行通信。A类网络号127是为环回接口预留的。根据惯例,大多数系统把IP地址127.0.0.1分配给这个接口,并命名为localhost。图中的关键点是:1)传给环回地址(一般是127.0.0.1)的任何数据均作为IP输入。2)创个广播地址和多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是因为广播传送和多播传送的定义包含主机本身。3)任何传给主机地址的数据均送到环回接口。链路层的数据帧的最大传输字节称作MTU,最大传输单元。不同类型的网络大多数都有一个上限。如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就需要进行分片,把数据报分成若干份,这样每一片都小于MTU。 当在同一网络的两台主机互相进行通信时,该网络的MTU是非常重要的。但是两台主机的通信要通过多阿哥网络,那么每个网络的链路层可能有不同的MTU,重要的就不是两台主机所在网络的MTU了,而是两台通信主机路径中的最小MTU。它被称作路径MTU。

TCP报文结构和功能简析
TCP:传输、控制、协议。TCP与UDP最大却别就在那个C上面,它充分实现了数据传输时各种控制功能。可以进行丢包重发控制,还可以对次序乱掉的数据包进行顺序控制,还能控制传输流量,这些是UDP中没有的。即T C P 提供一种面向连接的、可靠的字节流服务。TCP是一中面向有链接的协议,只有在确认对端存在的时候,才会发送分数据,从而也可以控制通信流量的浪费。什么是可靠的传输:不丢包、不损坏、不乱序、不重复。TCP通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制来实现可靠传输。接收端查询就收数据TCP首部中的序号和数据长度。将自己下一步应该接受的序列号作为确认应答返送回去。就这样,通过序列号和确认应答,TCP实现可靠传输。一般使用TCP首部用于控制的字段来管理连接。一个连接的建立和断开,正常过程中,至少需要来回共7个包才能完成。TCP首部的数据结构如图所示:TCP包首部为了便于理解,忽略选项部分,固定首部通常为20个字节,将按作用分类分析。前4个字节来标识了发送方的端口号和接收方的端口号,即该数据包由谁发送,由谁接收。前2个字节标识源端口号,紧接着2个字节标识目的端口号。即发送方:(11111111,1111111)2= (65535)10,除去0~1023.即接收方:(11111111,1111111)2= (65535)10,除去0~1023.TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置。首部中的序号字段值则是指的是本报文段所发送的数据的第一个字节的序号。长度为4字节,序号是32bit的无符号数,序号到达232- 1后又从0开始。ack:确认序号,即确认字节的序号,更确切地说,是发送确认的一端所期望收到的下一个序号。所谓的发送确认的一端就是将确认信息发出的一端。比如第二次握手的S端就是发送确认的一端。确认序号为上次接收的最后一个字节序号加1.只有确认标志位(ACK)为1的时候,确认序号才有效。也叫首部长度,占4个bit,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。TCP报文结构由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。“首部长度”是4位二进制数,单位是32位字,能表示的最大十进制数字是15。(1111)2=(15)10,即是15个32位,一个32位是4个字节,因此数据偏移的最大值是154=60个字节,这也是TCP首部的最大字节。因为固定首部的存在,数据偏移的值最小为20个字节,因此选项长度不能超过40字节*(减去20个字节的固定首部)。占6位,保留为今后使用,但目前应置为0。当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快发送(相当于高优先级的数据),而不要按原来的排队顺序来传送。例如,已经发送了很长的一个程序要在远地的主机上运行。但后来发现了一些问题,需要取消该程序的运行,因此用户从键盘发出中断命令。如果不使用紧急数据,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有的数据被处理完毕后这两个字符才被交付接收方的应用进程。这样做就浪费了很多时间。当URG置为1时,应用进程就告诉TCP有紧急数据要传送。于是TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍然是普通数据。这时要与首部中紧急指针(Urgent Pointer)字段配合使用。仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作。发送方TCP把PSH置为1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地(即“推送”向前)交付接收应用进程。而不用再等到整个缓存都填满了后再向上交付。当RST=1时,表明TCP连接中出现了严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立传输连接。RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。因此SYN=1就表示这是一个连接请求或连接接受报文。用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。占2字节。窗口值是(0,216-1)之间的整数。窗口指的是发送本报文段的一方的接受窗口(而不是自己的发送窗口),窗口大小是给对方用的。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方一次发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。例如,A发送了一个报文段,其确认号是3000,窗口字段是1000.这就是告诉对方B:“从3000算起,A接收缓存空间还可接受1000个字节数据,字节序号是3000-3999”,可以想象到河道的阀门。总之:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化。占2字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式和UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6);把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用TPv6,则相应的伪首部也要改变。占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据) 。因此,在紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据。长度可变,最长可达40个字节。当没有使用“选项”时,TCP的首部长度是20字节。最大报文段长度(MSS:Maximum Segment Size)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。当建立一个连接时,每一方都有用于通告它期望接收的MSS选项(MSS选项只能出现在SYN报文段中),如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节IP数据报) 。为什么要规定一个最大报文长度MSS呢?这并不是考虑接受方的接收缓存可能存放不下TCP报文段中的数据。实际上,MSS与接收窗口值没有关系。我们知道,TCP报文段的数据部分,至少要加上40字节的首部(TCP首部20字节和IP首部20字节,这里还没有考虑首部中的可选部分)才能组装成一个IP数据报。若选择较小的MSS长度,网络的利用率就降低。设想在极端情况下,当TCP报文段只含有1字节的数据时,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,对网络的利用率就不会超过1/41。到了数据链路层还要加上一些开销。但反过来,若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片组成成原来的TCP报文段,当传输出错时还要进行重传,这些也都会使开销增大。因此,MSS应尽可能大些,只要在IP层传输时不需要分片就行。由于IP数据报所经历的路径是动态变化的,因此在这条路径上确定的不需要的分片的MSS,如果改走另一条路径就可能需要进行分片。因此最佳的MSS是很难确定的。在连接过程中,双方都把自己能够支持的MSS写入这一字段,以后就按照这个数值传输数据,两个传送方向可以有不同的MSS值。若主机未填写这一项,则MSS的默认值是536字节长。因此,所有在互联网上的主机都应该接受的报文段长度是536+20(固定首部长度)=556字节。后来又增加了几个选项如窗口扩大选项、时间戳选项等。窗口扩大选项是为了扩大窗口。我们知道,TCP首部中窗口字段长度是16位,因此最大的窗口大小为64K字节。虽然这对早期的网络是足够用的,但对于包含卫星信道的网络,传播时延和宽带都很大,要获得高吞吐量需要更大的窗口大小。窗口扩大选项占3字节,其中有一个字节表示移位值S。新的窗口值等于TCP首部中的窗口位数从16增大到(16+S)。移位值允许使用的最大值是14,相当于窗口最大值增大到2(16+14)-1=230-1。窗口扩大选项可以在双方初始建立TCP连接时进行协商。如果连接的某一端实现了窗口扩大,当它不再需要扩大其窗口时,可发送S=0选项,使窗口大小回到16。时间戳选项占10字节,其中最主要的字段是时间戳字段(4字节)和时间戳回送回答字段(4字节)。时间戳选项有以下两个概念:第一、 用来计算往返时间RTT。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确地计算出RTT来。第二、 用于处理TCP序号超过232的情况,这又称为防止序号绕回PAWS。我们知道,TCP报文段的序号只有32位,而每增加232个序号就会重复使用原来用过的序号。当使用高速网络时,在一次TCP连接的数据传送中序号很可能被重复使用。例如,当使用1.5Mbit/s的速度发送报文段时,序号重复要6小时以上。但若用2.5Gbit/s的速率发送报文段,则不到14秒钟序号就会重复。为了使接收方能够把新的报文段和迟到很久的报文段区分开,则可以在报文段中加上这种时间戳。从功能和性能的角度去理解三次握手建立连接第一次:C向S发送一个建立连接的请求。此过程中携带一些报文属性信息,这些信息,存在于报文首部,有初始化用的信息,比如,有用于认证的信息。初始化信息:如报文序列号、SYN:TCP在数据通信之前,通过TCP首部发送的一个SYN标志位,作为建立连接的请求等待接收方确认应答。如果S发来确认应答,则认为可以进行数据通信,否则,就不能进行通信。TCP规定:****SYN=1的报文段不能携带数据,但是要消耗掉一个序号:seq=x。这个时候C进入SYN-SENT(同步已发送)状态。第二次:S收到C请求后,如果同意建立连接,则向C返回确认信息:将SYN、ACK都置1,确认号为ack=seq+1(seq来自客户端),并携带自己的初始化,同时用于认证的信息S。同理:SYN=1的报文段不能携带数据,但是要消耗掉一个序号:seq=y。这个时候S进入SYN-RCVD(同步已接收)状态。C收到S返回的确认信息后,进入ESTABLISHED(已建立连接)的状态,第三次:C收到S返回的确认信息后,向S再一次发送确认报文。ACK置为1,确认号ack=seq+1(seq来自S),自己的seq=x+1。TCP规定:ACK报文可以携带数据。但是,如果不携带数据,则不消耗序号,这时,下一数据报文段的序号仍是seq=x+1。服务器收到客户端返回的确认信息后,也进入ESTABLISHED(已建立连接)的状态,从功能角度去考虑前两次握手,从性能的角度去理解为什么需要第三次握手。有第三次,是考虑到一种错误情况:假设C发了一请求建立连接的报文,长时间未收到S的确认报文,则C会重发,这个时候S与之建立连接、完成数据通信、关闭了连接,这个时候C第一发出的请求建立连接的报文到达了S,S则会等待C发送数据,实际上C已经CLOSED了,S就一直在这等待,浪费资源,确切地说,应该是至少四次数据交互才能实现一个连接的彻底关闭。关闭连接,需要四个报文来指示关闭。TCP是全双工通信的,所以在一端发送数据完毕后,还具有接收另一端的数据的能力,这就所谓的半关闭。四次挥手举个例子:如果C的数据已经发送完毕,C是不能立即关闭的,因为建立连接的通信双方是平等的。C首先告诉S:“数据发送完毕“,这个消息在TCP报文的首部由FIN来标识,让S知道C是准备断开连接了。这是第一次挥手。S收到C发来的FIN标识的报文后,要给C端恢复一个确认FIN的消息,告诉C说,知道你的数据发完了。这是第二次挥手。这个时候,如果S端的数据也发送完毕了,就给C发一个FIN=1报文。这是第三次挥手。C收到S发来的FIN标识的报文后,要给S端恢复一个确认FIN的消息,告诉C说,知道你的数据发完了。这是第四次挥手。然后就彻底断开连接了。TCP的状态变迁图

TCP报文的格式及TCP协议的工作原理?
TCP报文格式 源端口和目的端口:都是16个比特,分别表示发送方和接收方的端口号。端口号和IP地址构成套接字(socket)地址的主要内容。源端和目的端的套接字合起来唯一地表示一条连接。网络应用程序在通信时直接向套接字发送和接收数据。序列号和确认号:都是32位的无符号整数,可以表示0-4G(232)字节的范围。其中,序列号表示数据部分第一个字节的序列号,而确认号表示该数据报的接收者希望对方发送的下一个字节的序号(即序号小于确认号的数据都已正确地被接收)。头长度(HLEN):表示TCP报文头的长度。长度以32-bit为单位来计算。所以如果选项部分的长度不是4个字节的整数倍,则要加上填充(padding)。保留域:紧接在头长度字段后有6个比特,应该把它设置为0。再后则是6个标志位。标志位特定的含义:URG(urgent)为紧急数据标志。如果它为1,则表示本数据报中包含紧急数据。此时紧急数据指针表示的值有效。它表示在紧急数据之后的第一个字节的偏侈值(即紧急数据的总长度)。ACK(acknowledge)为确认标志位。如果ACK为1,则表示报文中的确认号是有效的。否则,报文中的确认号无效,接收端可以忽略它。PSH(push)标志位。被置位后,要求发送方的TCP协议软件马上发送该数据报,接收方在收到数据后也应该立即上交给应用程序,即使其接收缓冲区尚未填满。RST(reset)标志位。用来复位一条连接。RST标志置位的报文称为复位报文。一般情况下,如果TCP收到的一个报文明显不是属于该主机上的任何个连接,则向远端发送一个复位报文。SYN(synchronous)标志位。用来建立连接,让连接双方同步序列号。如果SYN=1而ACK=0,则表示该数据报为连接请求,如SYN=1而ACK=1则表示是接受连接。FIN(finish)标志位。表示发送方已经没有数据要传输了,希望释放连接。窗口(window)字段。窗口表示的是从被确认的字节开始,发送方最多可以连续发送的字节的个数。接收方通过设置该窗口值的大小,可以调节源端发送数据的速度,从而实现流控。校验和(checksum)域。是TCP协议提供的一种检错机制。与我们在前面的章节中学过的UDP协议类似,在计算校验和时不仅要计算TCP报文自身(报文头和数据),还要增加一些额外的信息内容 – 12个字节的“伪包头”。TCP/IP(Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/互联网络协议)协议是Internet最基本的协议,简单地说,就是由底层的IP协议和TCP协议组成的。在Internet没有形成之前,各个地方已经建立了很多小型的网络,称为局域网,Internet的中文意义是“网际网”,它实际上就是将全球各地的局域网连接起来而形成的一个“网之间的网(即网际网)”。然而,在连接之前的各式各样的局域网却存在不同的网络结构和数据传输规则,将这些小网连接起来后各网之间要通过什么样的规则来传输数据呢?这就象世界上有很多个国家,各个国家的人说各自的语言,世界上任意两个人要怎样才能互相沟通呢?如果全世界的人都能够说同一种语言(即世界语),这个问题不就解决了吗?TCP/IP协议正是Internet上的“世界语”。 TCP/IP协议的开发工作始于70年代,是用于互联网的第一套协议。
懂英文的看这个吧...TCP的"官方文档"... http://tools.ietf.org/html/rfc793

TCP 详解
title: TCP 总结date: 2018-03-25 09:40:24tags:categories:-计算机网络我们都知道 TCP 是位于传输层的协议,他还有一个兄弟就是 UDP ,他们两共同构成了传输层。显然他们之间有很大的区别要不然的话在传输层只需要一个就好了。其中最重要的区别就是一个面向连接另外一个不是,这个区别就导致了他们是否能够保证稳定传输,显然不面向连接的 UDP 是没办法保证可靠传输的,他只能靠底层的网络层和链路层来保证。我们都知道网络层采用的是不可靠的 IP 协议。好吧,网络层也保证不了可靠传输,所以 UDP 保证可靠传输只能依靠链路层了。而 TCP 就好说了他不仅仅有底层的链路层的支持,还有自己的面向链接服务来保证可靠传输。当然 TCP也不仅仅就是比 UDP 多了一个可靠传输,前面也说到了这只是他们之间一个重要的区别。其实他的三个重要特性就是它们之间的区别。* 可靠传输* 流量控制* 拥塞控制TCP 主要是 确认重传机制 数据校验 数据合理分片和排序 流量控制 拥塞控制 依靠来完成可靠传输的 , 下面详细介绍这几种保证可靠传输的方式。确认重传,简单来说就是接收方收到报文以后给发送方一个 ACK 回复,说明自己已经收到了发送方发过来的数据。如果发送方等待了一个特定的时间还没有收到接收方的 ACK 他就认为数据包丢了,接收方没有收到就会重发这个数据包。好的,上面的机制还是比较好理解的,但是我们会发现一个问题,那就是如果接收方已经收到了数据然后返回的 ACK 丢失,发送方就会误判导致重发。而此时接收方就会收到冗余的数据,但是接收方怎么能判定这个数据是冗余的还是新的数据呢?这就涉及到了 TCP 的另外一个机制就是采用序号和确认号,也就是每次发送数据的时候这个报文段里面包括了当前报文段的序号和对上面的报文的确认号,这样我们的接收方可以根据自己接受缓存中已经有的数据来确定是否接受到了重复的报文段。这时候如果出现上面所说的 ACK 丢失,导致接受重复的报文段时客户端丢弃这个冗余的报文段。好现在我们大致了解了确认重传机制,但是还有些东西还没有弄清楚,也就是 TCP 真正的实现究竟是怎样的。这就是我们要解决的第一个问题就是如何确认。这里涉及到两种确认方式,分别称为 累计确认(捎带确认)和单停等协议。用一张图来快速理解,就是每发送一次数据,就进行一次确认。等发送方收到了 ACK 才能进行下一次的发送。一样的也是采用的 ACK 机制,但是注意一点的是,并非对于每一个报文段都进行确认,而仅仅对最后一个报文段确认,捎带的确认了上图中的 203 号及以前的报文。总结:从上面可以看到累计确认的效率更加高,首先他的确认包少一些那么也就是在网络中出现的大部分是需要传输的数据,而不是一半的数据一半的 ACK ,然后我们在第二张图中可以看到我们是可以连续发送多个报文段的(究竟一次性能发多少这个取决于发送窗口,而发送窗口又是由接受窗口和拥塞窗口一起来决定的。),一次性发多个数据会提高网络的吞吐量以及效率这个可以证明,比较简单这里不再赘述!结论:显然怎么看都是后者比较有优势,TCP 的实现者自然也是采用的累计确认的方式!上文中的那个特定的时间就是超时时间,为什么有这个值呢? 其实在发送端发送的时候就为数据启动了一个定时器,这个定时器的初始值就是超时时间。超时时间的计算其实有点麻烦,主要是我们很难确定一个确定的值,太长则进行了无意义的等待,太短就会导致冗余的包。TCP 的设计者们设计了一个计算超时时间的公式,这个公式概念比较多,有一点点麻烦,不过没关系我们一点点的来。首先我们自己思考如何设计一个超时时间的计算公式,超时时间一般肯定是和数据的传输时间有关系的,他必然要大于数据的往返时间(数据在发送端接收端往返一趟所用的时间)。好,那么我们就从往返时间下手,可是又有一个问题就是往返时间并不是固定的我们有如何确定这个值呢?自然我们会想到我们可以取一小段时间的往返时间的平均值来代表这一时间点的往返时间,也就是微积分的思想!好了我们找到了往返时间(RTT),接下来的超时时间应该就是往返时间再加上一个数就能得到超时时间了。这个数也应该是动态的,我们就选定为往返时间的波动差值,也就是相邻两个往返时间的差。下面给出我们所预估的超时时间(TimeOut)公式:很好,看到这里其实你已经差不多理解了超时时间的计算方式了,只不过我们这个公式不够完善,但是思路是对的。我们这时候来看看 TCP 的实现者们采用的方式。好的,这就是 TCP 实现的超时时间的方式,但是在实际的应用中并不是一直采用的这种方式。假如说我们现在网络状态非常的差,一直在丢包我们根本没必要这样计算,而是采用直接把原来的超时时间加倍作为新的超时时间。总结:好的现在我们知道了在两种情况下的超时时间的计算方式,正常的情况下我们采用的上面的比较复杂的计算公式,也就是RTT+波动值否则直接加倍上面我们看到在发送方等待一个超时重传时间后会开始重传,但是我们计算的超时重传时间也不定就很准,也就是说我们经常干的一件事就会是等待,而且一般等的时间还挺长。那么可不可以优化一下呢?当然,在 TCP 实现中是做了优化的,也就是这里说到的快速重传机制。他的原理就是在发送方收到三个冗余的 ACK 的时候,就开始重传那个报文段。那么为什么是三个冗余的 ACK 呢?注意三个冗余的 ACK 其实是四个 ACK 。我们先了解一下发送 ACK 策略,这个是RFC 5681 文档规定的。好的,那么现在我们可以看到如果出现了三个冗余的 ACK 他只可能是发生了两次情况三,也就是发送了两个比期望值大的数据。但是注意出现情况三有两种可能,一个是丢包,另外一个是乱序到达。比如说我们现在是数据乱序到达的,我们来看一下。第一种乱序情况另外一种乱序丢包情况结论: 很显然我们可以看到,如果发生了乱序有可能会出现三次冗余 ACK,但是如果发现了丢包必然会有三次冗余 ACK 发生,只是 ACK 数量可能更多但是不会比三次少在我们发现丢包以后我们需要重传,但是我们重传的方式也有两种方式可以选择分别是GBN和SR翻译过来就是拉回重传和选择重传。好其实我们已经能从名字上面看出来他们的作用方式了,拉回重传就是哪个地方没收到那么就从那个地方及以后的数据都重新传输,这个实现起来确实很简单,就是把发送窗口和接受窗口移回去,但是同样的我们发现这个方式不实用干了很多重复的事,效率低。那么选择重传就是你想到的谁丢了,就传谁。不存在做无用功的情况。结论:TCP 实际上使用的是两者的结合,称为选择确认,也就是允许 TCP 接收方有选择的确认失序的报文段,而不是累计确认最后一个正确接受的有序报文段。也就是跳过重传那些已经正确接受的乱序报文段。数据校验,其实这个比较简单就是头部的一个校验,然后进行数据校验的时候计算一遍 checkSum 比对一下。在 UDP 中,UDP 是直接把应用层的数据往对方的端口上 “扔” ,他基本没有任何的处理。所以说他发给网络层的数据如果大于1500字节,也就是大于MTU。这个时候发送方 IP 层就需要分片。把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组。这样就会多做许多事情,而更严重的是 ,由于UDP的特性,当某一片数据传送中丢失时 , 接收方便无法重组数据报,将导致丢弃整个UDP数据报。而在 TCP 中会按MTU合理分片,也就是在 TCP 中有一个概念叫做最大报文段长度(MSS)它规定了 TCP 的报文段的最大长度,注意这个不包括 TCP 的头,也就是他的典型值就是 1460 个字节(TCP 和 IP 的头各占用了 20 字节)。并且由于 TCP 是有序号和确认号的,接收方会缓存未按序到达的数据,根据序号重新排序报文段后再交给应用层。流量控制一般指的就是在接收方接受报文段的时候,应用层的上层程序可能在忙于做一些其他的事情,没有时间处理缓存中的数据,如果发送方在发送的时候不控制它的速度很有可能导致接受缓存溢出,导致数据丢失。相对的还有一种情况是由于两台主机之间的网络比较拥塞,如果发送方还是以一个比较快的速度发送的话就可能导致大量的丢包,这个时候也需要发送方降低发送的速度。虽然看起来上面的两种情况都是由于可能导致数据丢失而让发送主机降低发送速度,但是一定要把这两种情况分开,因为前者是属于 流量控制而后者是拥塞控制,那将是我们后面需要讨论的事情。不要把这两个概念混了。其实说到流量控制我们就不得不提一下滑动窗口协议,这个是流量控制的基础。由于 TCP 连接是一个全双工的也就是在发送的时候也是可以接受的,所以在发送端和接收端同时维持了发送窗口和接收窗口。这里为了方便讨论我们就按照单方向来讨论。接收方维持一个接受窗口,发送方一个发送窗口。发送的时候要知道接受窗口还有多少空间,也就是发送的数据量不能超过接受窗口的大小,否则就溢出了。而当我们收到一个接收方的 ACK 的时候我们就可以移动接受窗口把那些已经确认的数据滑动到窗口之外,发送窗口同理把确认的移出去。这样一直维持两个窗口大小,当接收方不能在接受数据的时候就把自己的窗口大小调整为 0 发送窗口就不会发送数据了。但是有一个问题,这个时候当接收窗口再调大的时候他不会主动通知发送方,这里采用的是发送方主动询问。还是画个图看的比较直观:拥塞控制一般都是由于网络中的主机发送的数据太多导致的拥塞,一般拥塞的都是一些负载比较高的路由,这时候为了获得更好的数据传输稳定性,我们必须采用拥塞控制,当然也为了减轻路由的负载防止崩溃。这里主要介绍两个拥塞控制的方法,一个是慢开始,另外一个称为快恢复。那么问题来了,为什么需要序号呢?为什么又是三次握手而不是两次?以及什么是 SYN 洪泛攻击?这里需要说明一下的是最后的那个长长的 TIME_WAIT 状态一般是为了客户端能够发出 ACK 一般他的值是 1分钟 或者2分钟好了,今天真的写了不少,主要就是把 TCP 的可靠传输以及连接管理讲清楚了,以及里面的一下细节问题,真的很花时间。然后其他没有涉及到的就是关于 TCP 的头并没有详细的去分析,这个东西其实也不是很难,但是现在篇幅真的已经很大就先这样,头里面的都是固定的不需要太多的理解。

本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/310066.html。