TCP/IP网络模型
物理层 | 数据链路层 | 网络层 | 传输层 | 应用层 | |
---|---|---|---|---|---|
功能 | 确定传输介质的材质、信道的复用、调制解调等 | 将数据可靠地传输到“相邻”节点(不经过路由器 的点对点 传输):封装成帧、同名传输、差错检测 | 网际通信(不同IP 的网络间通信):寻址,路由选择,尽力而为的无连接服务 | 为应用进程 提供逻辑通信 | |
传输单位 | 比特流 | 帧(比特流MAC地址的封装和解封装) | 数据包(帧的IP地址的封装和解封装) | ||
设备 | 转发器 | 交换机、网络适配器(网卡) | 路由器 | 电脑、网关(网络层以上的协议转换) | 电脑 |
协议 | 点对点信道:PPP;广播信道:CSMA/CD协议 | IP,APR,ICMP,IGMP(后面3个用于配合IP协议) | TCP/UDP | HTTP、Telnet、FTP、SMTP / NFS、SNMP、DNS、TFTP |
TCP/IP交换方式和连接方式
TCP可靠传输的实现
- 流量控制:当
接收方来不及处理
发送方的数据,能提示发送方降低发送的速率,防止包丢失。 - 拥塞控制:当
网络拥塞
时,减少数据的发送。 - 超时重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就会重传。
- 数据校验:TCP报文头有校验和,用于校验报文是否损坏
- 数据合理分片和排序
UDP:IP数据报大于1500字节,大于MTU.这个时候发送方IP层就需要分片(fragmentation).把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组.这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便无法重组数据报.将导致丢弃整个UDP数据报.
TCP:会按MTU合理分片,接收方会缓存未按序到达的数据,重新排序后再交给应用层。
TCP三次握手和四次挥手
TCP连接其实是一个双向的连接
,例如说,A与B两台电脑建立TCP连接时,实际A到B和B到A时看做两条通道的。
TCP为保证数据可靠性,采用超时重传
机制,即在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
- 三次握手
三次握手的过程
- 第一次握手: 建立连接时发送SYN会选择一个初始序号(ISN),每个连接的ISN都是不同的。客户端发送数据包(SYN=1,seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
- 第二次握手: 服务器收到数据包包,必须确认客户的SYN(ACK=1,ack=x+1),同时自己也发送一个SYN包(SYN=1,seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK=1(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
- 注意:
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
必须三次握手的原因
采用三次握手是为了防止失效的连接请求
报文段并没有丢失,只是在某处暂时滞留,后在连接释放后
的某个时间又传送到主机B,造成主机B的资源浪费
。失效的连接请求报文段是指:主机A向主机B发送的,在成功连接请求前的,连接请求。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。
上述特殊情况有以下注意点:
- 主机A发送请求后,一段时间接收不到确认会再次发送请求
- 主机A的连接请求失效,即A和B已经建立连接,但建立连接前A发送的请求没有丢失,而是被滞留
- A和B的连接断开后,失效的请求又到达主机B,造成误会
- 四次挥手
四次挥手的过程
- 第一次挥手: 主动断开连接一方向被动断开连接发送FIN数据包,FIN=1,seq=x,告诉被动断开连接一方“我要跟你断开连接了,我不会再给你发送数据了”,这是主动断开连接方式可以接受数据的,如果一直没有收到被动连接方的确认包,则可以重新发送这个包。此时,主动断开连接方处于FIN_WAIT_1状态
- 第二次挥手: 被动连接方接收到FIN包以后,发送确认包ACK=1,ack=x+1(FIN和SYN一样占用一个序列号),这个动作是告诉主动断开连接方我知道你要断开了,但是我还有数据没有发送完,等发送完了所有的数据就进行第三次挥手,此时被动断开连接方处于CLOSE_WAIT状态,主动断开连接方处于FIN_WAIT_2状态。
- 第三次挥手: 被动断开连接方发送FIN=1,seq=y+1包,用来停止向主动断开连接方发送数据,也就是告诉主动断开连接方,我的数据也发完了,我也不给你发数据了,此时被动断开连接方处于LAST_ACK状态,主动断开连接方处于TIME_WAIT 状态
- 第四次挥手: 等过了一定时间(
2MSL
(报文段最大生存时间):为了保证最后ACK报文能够到达B(A的ACK可能会丢失,B在一段时间内收不到会超时重传FIN+ACK报文,让A在2MSL期间收到,A可再次发送ACK),且为了防止已失效连接请求报文段出现在下一次新的连接中(经过2MSL的时间,可以让本连接持续时间内所产生的报文段都从网络中消失,防止对下次连接造成干扰))过后,主动断开连接方发送确认包ACK=1, ack=y+2,至此,四次挥手已经完成。
必须四次挥手的原因
双向连接的关闭的确认
- 第二次挥手的原因:B告知A我已经知道你不再发送了,我也将不再接收(从而让A确认其发送的“不再发送”的消息已经被B接收,B关闭接收功能)
- 第四次挥手的原因:A告知B我已经知道你不再发送了,我也将不再接收(从而让B确认其发送的“不再发送”的消息已经被A接收,A关闭接收功能)
TCP V.S. UDP
UDP | TCP |
---|---|
无连接:发送数据之前不需要建立连接(也就不需要释放连接) | 面向连接 :通信前需要先建立虚连接 (通过双向的消息、消息确认来模拟物理连接 ,不是真正意义上的面向连接),通信后需要释放连接 |
尽最大努力交付(因为无连接,所以不需要维持复杂的连接状态表而保证交付的可靠) | 提供可靠交付 服务:通过端系统保证数据的传输无差错、不丢失、不重复、按顺序到达 |
没有拥塞控制:网络拥塞了也照发不误,所以网络的拥塞不会让交互速度降低,增加了丢失的概率,但是降低了延时 | 需要拥塞控制 |
面向报文:应用层给多长报文,UDP不拆不组,原封不动发送(报文太长,IP会分组) | 面向字节流 :TCP把应用程序交下来的数据看成仅仅是一串无结构的字节流,根据对方给出的窗口值和当前网络拥塞的程度决定一个报文段应该包含多少字节(这样的划分会使得每个报文段没有逻辑上的含义,只剩下物理上大小的合理) |
支持一对一、一对多、多对一、多对多通信 | 只支持点对点传输 (此处的点指套接字 ) |
首部开销小 | 首部开销大 |
参考文献
https://troywu0.gitbooks.io/spark/content/tcpsan_ci_wo_shou.html 三次握手四次挥手的过程