第三章 传输层
传输层服务
该层的协议为应用进程提供端到端的通信服务,它提供面向连接的数据流支持、可靠性、流量控制、多路复用等服务。著名的TCP/IP传输协议是传输控制协议(TCP),TCP是一种面向连接的传输协议,而无连接的用户数据报协议用于简单消息传输。TCP是一种更复杂的传输协议,之所以复杂是因为它的设计要满足可靠传输和数据流服务。这个协议组中其他的重要协议有数据拥塞控制协议和流量控制传输协议。
多路复用与多路分解
端口可以在单个节点上提供多个端点。多路复用根据使用的技术可以分为时分复用、频分复用、空分复用和码分复用。
- 发送主机上的多路分解:将收到的报文段递交给正确的套接字,即恰当的进程。
- 接收主机上的多路复用:从多个套接字收集数据,用首部封装数据。
多路分解的工作原理
一个进程(作为网络应用的一部分)有一个或多个套接字(socket),它相当于从网络向进程传递数据和从进程向网络传递数据的门户。将运输层报文段中的数据交付到正确的套接字的工作称为多路分解。
DUP无连接多路分解
TCP面向连接多路分解
UDP:用户数据报协议
- 特点:
- 无连接、不可靠
- 用途:
- DNS
- SNMP
- 流多媒体应用
- 可靠传输:
- 在应用层增加可靠性
- 应用层程序有特定的错误恢复
- 优点:
- 不需要连接状态
- 首部小(8字节)
- 没有拥塞控制
UDP报文头部
UDP校验和
可靠数据传输原理
有限状态机
状态:在当前“状态”下,由一个事件唯一确定下一个状态
rdt的复杂性
- rdt1.0:理想化
- rdt2.0:有bit错误的信道
- rdt3.0:具有出错和丢包的信道
rdt3.0:stop and wait operation
管道化协议(Pipelined protocols)
增加利用率
回退N协议(GBN)
- 操作
- 有限状态机
选择重传协议
TCP概要
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP报文段结构
TCP可靠数据传输
三次握手创建连接
- 客户端(通过执行connect函数)向服务器端发送一个SYN包,请求一个主动打开。该包携带了客户端为这个连接请求而设定的随机数A作为消息队列号。
- 服务端收到一个合法的SYN包后,把该包放入SYN队列;会送一个SYN/ACK。ACK的确认码应为A+1,SYN/ACK包本身携带一个随机产生的序号B。
- 客户端收到一个SYN/ACK包后,发送一个ACK包,该包的序号被设定为A+1,而ACK的确认码则为B+1。
为什么需要进行三次握手?
三次握手的主要目的是为了防止已经失效的连接请求报文突然又传到服务器,从而产生错误。
可以这样来理解这个问题,当客户端向服务器发送一个连接请求报文的时候,由于某些原因该报文在网路中发生了滞留,而当该报文到达服务端的时候此时客户端和服务端的连接请求已经完成,不需要再进行连接。服务端没有那么的智能,当他收到一个连接请求报文的时候,就会对该报文做出相应,向客户端发送一个响应报文SYN/ACK。如果只采用两次连接的话,此时连接就已经建立完成,但是客户端并不会向服务器发送数据,而服务器会一直等待客户端发送数据,在这个过程中服务器所占用的系统资源并不会释放,很多资源就会白白浪费。而如果采用三次握手建立连接的话,只要客户端不对服务器发送的SYN/ACK报文做出响应,发送ACK报文,连接就不会建立,服务器端也不会由此白白的浪费系统资源。
问题的本质是信道是不可靠的,而我们要建立可靠的连接,发送可靠的数据。这个时候三次握手是为了满足可靠传输的最小值,并不是TCP传输协议所规定的。
四次挥手释放连接
在进行连接释放的过程中每一侧都独立的被终止。当一个端点要终止它这一侧的连接,就向对侧发送FIN,对侧恢复ACK表示确认。因此拆掉一侧的连接过程需要一对FIN和ACK,分别由两侧端点发出。
连接可以工作在TCP半开状态。即一侧关闭了连接,不再发送数据;但另一侧没有关闭连接,仍然可以发送数据。已关闭的一侧仍然应接收数据,直至对侧也关闭了连接。
为什么需要进行四次挥手?三次挥手可以吗?
如果是三次挥手,那么被动关闭端在收到客户端发送的FIN消息后,要同时回复ACK和服务端的FIN消息。如果服务端此时没有Pending的消息需要处理,那么这样做是可行的,但是如果服务端还需要等待一段时间才能够关闭另一个方向上的连接,那么,这种情况下三次挥手就不能满足条件。
为什么客户端发送完最后一个确认报文后还需要等待2MSL的时间?
- 由于客户端最后一个ACK可能会丢失,这样B就无法正常进入CLOSED状态。于是B会重传请求释放的报文,而此时A如果已经关闭了,那么就收不到B的重传请求,就会导致B不能正常释放。而如果A还在等待时间内,就会收到B的重传,然后进行应答,这样B就可以进入CLOSED状态了。
- 在这2MSL等待时间里面,本次连接的所有报文都已经从网络中消失,从而不会出现在下一次的连接中。
TCP发送方事件:3个
NextSeqNum = InitialSeqNum SendBase = InitialSeqNum loop (forever) { switch(event) event: data received from application above create TCP segment with sequence number NextSeqNum if (timer currently not running) start timer pass segment to IP NextSeqNum = NextSeqNum + length(data) event: timer timeout retransmit not yet acknowledged segment with smallest sequence number y start timer event: ACK received, with ACK field value of y if (y > SendBase) { /* 累计确认到 Y */ SendBase = y if (there are currently not yet acknowledged segments) start timer } } /* end of loop forever */
- 从应用层接收数据
- 超时
- 收到确认ACK
TCP发送方快速重传
流量控制
连接管理
拥塞控制
太多的源端发送太多太快的 数据,以至于网络来不及处理。
表现:丢包、长延时
拥塞避免(加增乘减)
慢启动
快速恢复
(阐述一下TCP的拥塞控制机制)
一个进程是否可以绑定多个端口号?
可以,因为一个进程可以打开多个文件描述符,而每个文件描述符都对应一个端口号,所以一个进程可以绑定多个端口号。
一个端口号是否可以被多个进程绑定?
不可以。注意:如果线程先绑定一个端口号,然后再fork一个子进程,这样的话就可以实现多个进程绑定一个端口号,但是两个不同的进程绑定同一个端口号是不可以的。