传输层的核心协议是TCP和UDP
。
TCP提供一对一的、面向连接的可靠通信服务。TCP建立连接,对发送的数据包进行排序和确认,并恢复在传输过程中丢失的数据包。 UDP提供一对一或一对多的、无连接的不可靠通信服务。
- 对程序发送的大块数据进行分段和重组。
- 确保正确排序及按顺序传递分段的数据。
- 通过计算校验和,进行传输数据的完整性检查。
- 根据数据是否接收成功发送肯定消息。通过使用选择性确认,也对没有收到的数据发送否定确认。
syn序列号和ACK确认号:可以看作是一个32bit
的计数器
-
第一次:建立连接时,客户端发送syn包(syn=j)到服务器,并进入
SYN_SENT
状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers
);(此时序列号是客户端随机产生的一个值,确认号是0) -
第二次:服务器收到syn包,必须确认客户的SYN,同时自己也发送一个SYN包,即
SYN+ACK
包,此时服务器进入SYN_RECV
状态;(此时服务器的序列号是随机产生的值,确认号是收到客户端序列号的值+1) -
第三次:客户端收到服务器的
SYN+ACK
包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入ESTABLISHED
(TCP连接成功)状态,完成三次握手.(此时确认号是收到服务器的序列号+1,)
在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于SYN_RECV
状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED
状态。
- 第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。
- 第二步,主机B收到这个
FIN
报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK
,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK
的目的是为了防止在这段时间内,对方重传FIN
报文段)。 - 第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个
FIN
报文段。 - 第四步,主机A收到这个
FIN
报文段后,向主机B发送一个ACK
表示连接彻底释放。
也就是说不双向确认的话,如果出现以下异常情况,即A发出第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了。以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段。但B收到此失效的连接请求后就误认为这是A又发出的一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假设不采用三次握手,那么只要B发出确认,新的连接就建立了。 由于A并没有发出新的连接请求。因此不会理睬B的确认,也不会向B发送数据。但B却以为新的连接已经建立了,一直等待A发送数据过来。这样B的许多资源就浪费了。
那么采用三次握手的话。当B发出确认后,A应该向B的确认发出确认。这样B收到A的确认后才会建立连接。以上B发出确认后,并没有收到A的确认,因此就知道连接并没有建立。
因为当服务端收到客户端的FIN报文时,并不会立刻关闭连接,因为有可能服务端收到FIN
报文时数据还没有完全接收完,此时服务端应该发送一个确认号ACK
告诉客户端我已经收到FIN
报文,避免客户端重新发送FIN
报文。
等服务端通知应用程序要关闭连接,并且数据已经发送完毕后才向客户端发送一个FIN
报文,表示可以关闭连接。
UDP
提供无连接的网络服务,该服务对消息中传输的数据提供不可靠的、最大努力传送。这意味着它不保证数据报的到达,也不保证所传送数据包的顺序是否正确。
- UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
- 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
- UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
- 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
- UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
- UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
我们经常使用“ping
”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping
”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。