(现在不在学校,TCP/IP协议不在手,全凭记忆和网上资料,不周全的地方回校再补记)
基础部分:
TCP/UDP:
这两个是在传输层上的协议,之上就是SSH,HTTTP,FTP,SMTP等网络应用层,负责管理连接的发起和断开,接受和发送的数据如何解释。之下是负责将数据经由哪个路由传递的IP地址协议。那这个传输层用来干什么呢?用来负责数据传输的可靠。因为IP只负责路由选择和传输,但IP本身没有负责可靠的数据传输的机制。
你会想到可不可以在应用层面负责处理传输的可靠性,不用传输层的TCP协议。没有问题。但在处理的过程中,你会发现,当你想使用可靠传输时,会自然的总结出一套与TCP相似的规矩:比如三次握手与四次挥手负责一个可靠连接,序列号机制负责可靠传输,窗口控制与重发(google的BBR算法已经替代了拥塞控制成为linux内核算法,我会再写一篇来总结),那么作为一种几乎所有应用都需要的一套机制,它自然会抽离出来成为传输的基石。而当你不想可靠传输时(比如实时的音频视频,重传会很怪异),面向无连接,任性的发送的UDP也可以被抽象出来,作为传输的底层。
当然,ip层为什么不保证有效的传输呢?开始的网络是基于电话线路搭建的。由于电话是不智能的,因此只能在线路上进行操作保证数据的有效传输。而电脑是可以操控的,在上层操控保证数据的有效明显更灵活,成本也更低。
关于TCP的报文格式,如果理解了TCP的原理就很好理解了。这里先介绍TCP的几个机制。
建立连接与关闭连接。关于三次挥手可以这么理解:这里假设你是客户端,主动向服务器发起请求。你想要可靠的传输数据,保证对方能收到,并且自己可以接到对方的数据,最简单的就是发送数据包(SYN),看对方能不能据此回传一个(ACK)。然后服务器还不知道你是否能接收到他的信息。于是服务器发一个数据包(SYN),自己再据此回传(ACK)一个。然后,就可以认为两方可以可靠通信了。所以,其实应该是四次握手。但由于对方回传数据包和主动发数据包是可以同时的,那就可简化为三次握手。那挥手呢?你要告诉服务器我没什么要传的了(FIN),然后服务器会据此回传一个包(ACK)给你。这个包只是告诉你服务器接收到了。但这时你还不能关闭接收端口(此时自己为半关闭状态,即只关闭了发送端口),因为你还不确定服务器是不是还有东西没发送完。你要等待服务器发送完给你的数据,再向你发包(FIN),你确认了之后(ACK),双方才能关闭端口。之所以不能像握手一样简化,是因为服务器如果在接受到FIN后,还有很多数据没发完,会向你继续发送数据。这段时间内你会揣揣不安--是不是自己的包没有被接收,要不要重发。所以服务器直接向你挥手,然后你只需等待服务器端的最终的FIN包即可。
序列号实现可靠传输。每个数据包发送时带着一个随机序列号,比如说是201,对方接收后根据序列号和包中数据的长度,比如1000,返回给你1201的确认包,这样你就可以知道他接收到了,然后放心的发送。依靠这种机制,你可以确定每个包对方都接收到了,并且包的顺序也得到了保证。若在规定的时间内没有接收到确认包,再进行超时重传。没有接受到有两种情况,可能是没有发送过去,也可能是对方的应答包没有收到,这两种都算做网络故障,