网络技术 三次握手 四次挥手
tcpdump
Wireshark https://www.wireshark.org/download.html
https://www.cnblogs.com/howhy/p/6396664.html
TCP/IP协议是什么?
根据TCP/IP协议,我们可以把网络分成四层,分别为应用层,传输层,网际互联层以及网络接口层。而在ISO模型中,网络又可以分成七个层次,分别为应用层,表示层,会话层,传输层,网络层,数据链路层和物理层。为了研究方便,一般把网络分成四个层次,即应用层,传输层,网际互联层,网络接口层。
TCP/IP协议有什么用?
TCP/IP协议解决了互联网中,数据怎么从一台主机传输到另外一台主机的问题。
OSI七层模型和 TCP四层模型 各个层次及其功能
1.网络接口层(数据链路层和物理层)(主机-网络层)
- 网络接口层与OSI参考模型中的物理层和数据链路层相对应。
- 它负责监视数据在主机和网络之间的交换。
- 事实上,TCP/IP本身并未定义该层的协议,而由参与互连的各网络使用自己的物理层和数据链路层协议,然后与TCP/IP的网络接入层进行连接。
- 地址解析协议(ARP)工作在此层,即OSI参考模型的数据链路层。
数据链路层实现了网卡接口的网络驱动程序,以处理数据在物理媒介(比如以太网、令牌环等)上的传输。
数据链路层两个常用的协议是ARP协议(Address Resolve Protocol,地址解析协议)和RARP协议(ReverseAddress Resolve Protocol,逆地址解析协议)。它们实现了IP地址和机器物理地址(通常是MAC地址,以太网、令牌环和802.11无线网络都使用MAC地址)之间的相互转换。
网络层使用IP地址寻址一台机器,而数据链路层使用物理地址寻址一台机器,因此网络层必须先将目标机器的IP地址转化成其物理地址,才能使用数据链路层提供的服务,这就是ARP协议的用途。
2.网际互联层(网络层)
- 网际互联层对应于OSI参考模型的网络层。
- 主要解决主机到主机的通信问题。
- 它所包含的协议设计数据包在整个网络上的逻辑传输。
- 注重重新赋予主机一个IP地址来完成对主机的寻址。
- 它还负责数据包在多种网络中的路由。
- 该层有三个主要协议:网际协议(IP)、互联网组管理协议(IGMP)和互联网控制报文协议(ICMP)。
- IP协议是网际互联层最重要的协议,它提供的是一个可靠、无连接的数据报传递服务。
网络层实现数据包的选路和转发。
WAN(Wide Area Network,广域网)通常使用众多分级的路由器来连接分散的主机或LAN(Local Area Network,局域网),因此,通信的两台主机一般不是直接相连的,而是通过多个中间节点(路由器)连接的。网络层的任务就是选择这些中间节点,以确定两台主机之间的通信路径。同时,网络层对上层协议隐藏了网络拓扑连接的细节,使得在传输层和网络应用程序看来,通信的双方是直接相连的。
网络层最核心的协议是IP协议(Internet Protocol,因特网协议)。IP协议根据数据包的目的IP地址来决定如何投递它。如果数据包不能直接发送给目标主机,那么IP协议就为它寻找一个合适的下一跳(next hop)路由器,并将数据包交付给该路由器来转发。多次重复这一过程,数据包最终到达目标主机,或者由于发送失败而被丢弃。可见,IP协议使用逐跳(hop by hop)的方式确定通信路径。
网络层另外一个重要的协议是ICMP协议(Internet Control Message Protocol,因特网控制报文协议)。它是IP协议的重要补充,主要用于检测网络连接。
8位类型字段用于区分报文类型。它将ICMP报文分为两大类
差错报文,这类报文主要用来回应网络错误,比如目标不可到达(类型值为3)和重定向(类型值为5);
查询报文,这类报文用来查询网络信息,比如ping程序就是使用ICMP报文查看目标是否可到达(类型值为8)的。
有的ICMP报文还使用8位代码字段来进一步细分不同的条件。比如重定向报文使用代码值0表示对网络重定向,代码值1表示对主机重定向。
ICMP报文使用16位校验和字段对整个报文(包括头部和内容部分)进行循环冗余校验(Cyclic Redundancy Check,CRC),以检验报文在传输过程中是否损坏。不同的ICMP报文类型具有不同的正文内容。
3.传输层
- 传输层对应于OSI参考模型的传输层。
- 为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。
- 该层定义了两个主要的协议:传输控制协议(TCP)和用户数据报协议(UDP).
- TCP协议提供的是一种可靠的、通过“三次握手”来连接的数据传输服务;而UDP协议提供的则是不保证可靠的(并不是不可靠)、无连接的数据传输服务.
传输层为两台主机上的应用程序提供端到端(end to end)的通信。与网络层使用的逐跳通信方式不同,传输层只关心通信的起始端和目的端,而不在乎数据包的中转过程。
垂直的实线箭头表示TCP/IP协议族各层之间的实体通信(数据包确实是沿着这些线路传递的),而水平的虚线箭头表示逻辑通信线路。该图中还附带描述了不同物理网络的连接方法。可见,
数据链路层(驱动程序)封装了物理网络的电气细节;网络层封装了网络连接的细节;传输层则为应用程序封装了一条端到端的逻辑通信链路,它负责数据的收发、链路的超时重连等。
传输层协议:TCP协议、UDP协议。
TCP协议(Transmission Control Protocol,传输控制协议)为应用层提供可靠的、面向连接的和基于流(stream)的服务。TCP协议使用超时重传、数据确认等方式来确保数据包被正确地发送至目的端,因此TCP服务是可靠的。使用TCP协议通信的双方必须先建立TCP连接,并在内核中为该连接维持一些必要的数据结构,比如连接的状态、读写缓冲区,以及诸多定时器等。当通信结束时,双方必须关闭连接以释放这些内核数据。TCP服务是基于流的。基于流的数据没有边界(长度)限制,它源源不断地从通信的一端流入另一端。发送端可以逐个字节地向数据流中写入数据,接收端也可以逐个字节地将它们读出。
UDP协议(User Datagram Protocol,用户数据报协议)则与TCP协议完全相反,它为应用层提供不可靠、无连接和基于数据报的服务。“不可靠”意味着UDP协议无法保证数据从发送端正确地传送到目的端。如果数据在中途丢失,或者目的端通过数据校验发现数据错误而将其丢弃,则UDP协议只是单地通知应用程序发送失败。因此,使用UDP协议的应用程序通常要自己处理数据确认、超时重传等逻辑。UDP协议是无连接的,即通信双方不保持一个长久的联系,因此应用程序每次发送数据都要明确指定接收端的地址(IP地址等信息)。基于数据报的服务,是相对基于流的服务而言的。每个UDP数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出,否则数据将被截断。
4.应用层
- 应用层对应OSI参考模型的应用层、表示层和会话层。
- 应用层面向不同的网络应用引入了不同的应用层协议。其中,
- 有基于TCP协议的,如文件传输协议(File Transfer Protocol,FTP)、虚拟终端协议(TELNET)、超文本传输协议(Hyper Text TransferProtocol,HTTP),
- 也有基于UDP协议的,如网络时间协议(Network Time Protocol,NTP)、简单文件传输协议(Trivial File Transfer Protocol,TFTP)、简单网络管理协议(SNMP)
- DNS(Domain Name Service)是域名解析服务,提供域名到IP地址之间的转换—-可以基于TCP也可以基于UDP。
应用层负责处理应用程序的逻辑。
数据链路层、网络层和传输层负责处理网络通信细节,这部分必须既稳定又高效,因此它们都在内核空间中实现。而应用层则在用户空间实现,因为它负责处理众多逻辑,比如文件传输、名称查询和网络管理等。如果应用层也在内核中实现,则会使内核变得非常庞大。当然,也有少数服务器程序是在内核中实现的,这样代码就无须在用户空间和内核空间来回切换(主要是数据的复制),极大地提高了工作效率。不过这种代码实现起来较复杂,不够灵活,且不便于移植。
ping是应用程序,而不是协议,前面说过它利用ICMP报文检测网络连接,是调试网络环境的必备工具。
telnet协议是一种远程登录协议,它使我们能在本地完成远程任务。
OSPF(Open Shortest Path First,开放最短路径优先)协议是一种动态路由更新协议,用于路由器之间的通信,以告知对方各自的路由信息。
DNS(Domain Name Service,域名服务)协议提供机器域名到IP地址的转换。
应用层协议(或程序)可能跳过传输层直接使用网络层提供的服务,比如ping程序和OSPF协议。应用层协议(或程序)通常既可以使用TCP服务,又可以使用UDP服务,比如DNS协议。我们可以通过/etc/services文件查看所有知名的应用层协议,以及它们都能使用哪些传输层服务。
协议背后的思想:上层屏蔽下层细节,只使用其提供的服务。高内聚低耦合,每一层专注于其功能,各层之间的关系依赖不大。
数据包在每层有不同的格式,从上到下依次叫段,数据报,帧,数据从应用层通过协议栈向下传递,每经过一层加上对应层协议的报头,最后封装成帧发送到传输介质上,到达路由器或者目的主机剥掉头部,交付给上层需要者。这一过程称为封装,传输,分离,分用。
TCP/IP四层参考模型所涉及的网络协议
TCP/IP层级 | 相关的网络协议 |
---|---|
网络接口层 | ARP协议(地址解析协议) |
网际互联层 | IP协议(网际协议)、ICMP协议(互联网控制报文协议) |
传输层 | TCP协议(传输控制协议)、UDP协议(用户数据报协议) |
应用层 | HTTP协议(超文本传输协议)、NTP协议(网络时间协议)、TELNET协议(虚拟终端协议)、DNS协议(域名解析协议)、FTP协议(文件传输协议)、TFTP协议(简单文件传输协议)、SNMP协议(简单网络管理协议)、SMTP协议(简单邮件传输协议)、POP协议(邮局协议) |
备注:
ping 采用的是ICMP协议(互联网控制报文协议)
发送邮件采用SMTP、接收邮件采用POP3(邮局协议版本3)
在第一步中,客户端向服务端提出连接请求。这时TCP SYN标志置位。客户端告诉服务端序列号区域合法,需要检查。客户端在TCP报头的序列号区中插入自己的ISN。服务端收到该TCP分段后,在第二步以自己的ISN回应(SYN标志置位),同时确认收到客户端的第一个TCP分段(ACK标志置位)。在第三步中,客户端确认收到服务端的ISN(ACK标志置位)。到此为止建立完整的TCP连接,开始全双工模式的数据传输过程。
第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
传输数据过程:
超时重传
超时重传机制用来保证TCP传输的可靠性。每次发送数据包时,发送的数据报都有seq号,接收端收到数据后,会回复ack进行确认,表示某一seq号数据已经收到。发送方在发送了某个seq包后,等待一段时间,如果没有收到对应的ack回复,就会认为报文丢失,会重传这个数据包。
快速重传
接受数据一方发现有数据包丢掉了。就会发送ack报文告诉发送端重传丢失的报文。如果发送端连续收到标号相同的ack包,则会触发客户端的快速重传(不用等到超时计时器结束即可确认数据包已经丢失)。比较超时重传和快速重传,可以发现超时重传是发送端在傻等超时,然后触发重传;而快速重传则是接收端主动告诉发送端数据没收到,然后触发发送端重传。
流量控制
这里主要说TCP滑动窗流量控制。TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。 滑动窗可以是提高TCP传输效率的一种机制。
拥塞控制
滑动窗用来做流量控制。流量控制只关注发送端和接受端自身的状况,而没有考虑整个网络的通信情况。拥塞控制,则是基于整个网络来考虑的。考虑一下这样的场景:某一时刻网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。为此,TCP引入了拥塞控制策略。拥塞策略算法主要包括:慢启动,拥塞避免,拥塞发生,快速恢复。
这里有必要介绍一下TCP分段中的标志(Flag)置位情况。如下图所示:
*SYN:同步标志
同步序列编号(Synchronize Sequence Numbers)栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。
*ACK:确认标志
确认编号(Acknowledgement Number)栏有效。大多数情况下该标志位是置位的。TCP报头内的确认编号栏内包含的确认编号(w+1,Figure-1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据。
*RST:复位标志
复位标志有效。用于复位相应的TCP连接。
*URG:紧急标志
紧急(The urgent pointer) 标志有效。紧急标志置位,
*PSH:推标志
该标志置位时,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的。
*FIN:结束标志
带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。
四次挥手关闭TCP连接的各状态
(1)首先A B端的TCP进程都处于established状态, 当A的应用程序传送完报文段,就会去主动关闭连接。A会停止发送报文段(但是还会接收),并向B发送[FIN = 1,seq=u]数据,之后进入FIN-WAIT-1状态;
(2)B接收到A发送的请求之后,会通知应用进程,A已经不再发送数据,同时B会向A发送ACK确认数据[ACK=1,seq=v,ack=u+1 ],B进入CLOSE-WAIT状态,A接收到B发送的数据之后,A进入FIN-WAIT-2状态;此时A到B方的连接已经关闭了(即半连接状态)。
(3)当B的应用进程发现自己也没有数据需要传送,B应用进程就会发出被动关闭的请求,B此时向A发送[FIN=1,ACK=1,seq=w,ack=u+1]数据,并且进入LAST-ACK状态;
(4)A接收到B发送的数据之后,向B发送ACK确认数据[ACK =1,seq=u+1,ack=w+1],进入TIME-WAIT状态,等待2MSL之后正常关闭连接进入CLOSED状态;B接收到A发送的确认之后进入CLOSED状态。B到A方的连接关闭!至此,TCP连接才真正全部关闭!
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
CLOSED:起始点,在超时或者连接关闭时候进入此状态。
LISTEN:服务端在等待连接过来时候的状态,服务端为此要调用socket,bind,listen函数,就能进入此状态。此称为应用程序被动打开(等待客户端来连接)。
SYN_SENT:客户端发起连接,发送SYN给服务器端。如果服务器端不能连接,则直接进入CLOSED状态。
SYN_RCVD:跟3对应,服务器端接受客户端的SYN请求,服务器端由LISTEN状态进入SYN_RCVD状态。同时服务器端要回应一个ACK,同时发送一个SYN给客户端;另外一种情况,客户端在发起SYN的同时接收到服务器端得SYN请求,客户端就会由SYN_SENT到SYN_RCVD状态。
ESTABLISHED:服务器端和客户端在完成3次握手进入状态,说明已经可以开始传输数据了。
以上是建立连接时服务器端和客户端产生的状态转移说明。相对来说比较简单明了,如果你对三次握手比较熟悉,建立连接时的状态转移还是很容易理解。
下面,我们来看看连接关闭时候的状态转移说明,关闭需要进行4次双方的交互,还包括要处理一些善后工作(TIME_WAIT状态),注意,这里主动关闭的一方或被动关闭的一方不是指特指服务器端或者客户端,是相对于谁先发起关闭请求来说的:
FIN_WAIT_1:主动关闭的一方,由状态5进入此状态。具体的动作是发送FIN给对方。
FIN_WAIT_2:主动关闭的一方,接收到对方的FIN-ACK(即fin包的回应包),进入此状态。
CLOSE_WAIT:接收到FIN以后,被动关闭的一方进入此状态。具体动作是接收到FIN,同时发送ACK。(之所以叫close_wait可以理解为被动关闭方此时正在等待上层应用发出关闭连接指令)
LAST_ACK:被动关闭的一方,发起关闭请求,由状态8进入此状态。具体动作是发送FIN给对方,同时在接收到ACK时进入CLOSED状态。
CLOSING:两边同时发起关闭请求时,会由FIN_WAIT_1进入此状态。具体动作是接收到FIN请求,同时响应一个ACK。
TIME_WAIT:最纠结的状态来了。从状态图上可以看出,有3个状态可以转化成它,我们一一来分析:
a. 由FIN_WAIT_2进入此状态:在双方不同时发起FIN的情况下,主动关闭的一方在完成自身发起的关闭请求后,接收到被动关闭一方的FIN后进入的状态。
b. 由CLOSING状态进入:双方同时发起关闭,都做了发起FIN的请求,同时接收到了FIN并做了ACK的情况下,由CLOSING状态进入。
c. 由FIN_WAIT_1状态进入:同时接受到FIN(对方发起),ACK(本身发起的FIN回应),与b的区别在于本身发起的FIN回应的ACK先于对方的FIN请求到达,而b是FIN先到达。这种情况概率最小。
关闭的4次连接最难理解的状态是TIME_WAIT,存在TIME_WAIT的2个理由:
可靠地实现TCP全双工连接的终止。 允许老的重复分节在网络中消逝。
TCP端口
为了能够支持同时发生的并行访问请求,TCP提供一种叫做“端口”的用户接口。端口是操作系统核心用来识别不同的网络回话过程。这是一个严格的传输层定义。通过TCP端口和IP地址的配合使用,可以提供到达终端的通讯手段。实际上,在任一时刻的互联网络连接可以由4个数字进行描述: 来源IP地址和来源端口,目的IP地址和目的端口。位于不同系统平台,用来提供服务的一端通过标准的端口提供相应服务。举例来说,标准的TELNET守护进程(telnet daemon)通过监听TCP 23端口,准备接收用户端的连接请求。
1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到客户端的SYN报文的建立连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到 ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于 LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的 ACK报文。