计算机之间的通信其实大多指的是计算机进程之间的通信,而传输层就是基于网络层IP协议提供的功能将数据报发送到计算机的另一个进程。当然传输层协议也提供了自己的一些功能,例如流量控制,安全控制,拥塞控制等。下面我们将讨论传输层2个重要的协议UDP(用户数据报协议)和TCP(传输控制协议)。
要理解进程间的通信我们必须了套接字和端口的概念。因为在面对成千上万的进程中,客户端怎么知道和服务器端的哪个进程进行通信呢,同样服务器端也是如此。进程间正是通过端口与套接字实现的。简单的间端口和套接字就是提供一种统一的格式来唯一的标实参与通信的进程。
一:端口与套接字
端口:计算机与外界进行交流的出口。(物理端口:又称为接口,能够看见的。比如电话线的接口;虚拟端口:比如TCP端口,UDP端口)
套接字:在数据传输的过程中,当多个进程并发的使用同一个端口的时候,为了区分是与哪一个进程进行通信,那么应用层可以通过套接字接口绑定特定的进程,实现进程间的通信。
二:UDP(用户数据报协议)
UDP:一个面向无连接的协议,所以它是不可靠的协议。它可以看成是非常瘦的一个协议,因为除了提供多路端口分解以外,没有提供其他功能。因为它的开销很小,同时传输速度相对来书比较快,比较典型的例子是QQ的文件传输。虽然他没有提供诸如安全性的要求,但是它要求函数来实现这些功能。
三:TCP(传输控制协议)
TCP:一个面向链接的协议,同时提供了流量控制,拥塞控制,差错回复等功能,所以它是一个安全的协议。
1:TCP的“三次握手建立链接”
第一次:
客户端主动向服务器发送一个SYN(SYN=j)(同步序列编号)包,并进入SYN-SEND状态。等待服务器的响应。
第二次:
服务器收到SYN包时,必须确认这个SYN包(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即会发送一个SYN+ACK包,并且进入SYN-RESIVE状态。
第三次:
客户端接收到服务器端的SYN+ACK包后向客户端在发送一个ACK(ack+1)包,这时候就进入链接状态。
提问:为什么不是俩次握手建立链接,而最少要三次呢?
相信很多人都会发现其实在2次握手时就进入表示服务器端有相应,那么为什么不是2次握手进入连接状态呢?那我们来考虑一个问题,加入在一次通信的过程中一个包丢失了。但是在某一时刻这个确到达了服务器端,同样服务器会向客户端发送确认宝包,而这并不是需要连接建立的请求,如果2次握手的话,这样就会进入连接状态。所以最少3次握手是比较安全的做法。
2:TCP的拥塞控制算法:
1:慢速启动:
在过去的链接时,服务器端将告诉其窗口的大小,这样客户端将发送多个包过去,这样在2个直连的设备间看起来是不错的,但是在有像路由器等中间设备的时候,有些包会丢失,有些设备的传输速度有不是想象的那么理想,这样就会发生拥塞。TCP的一个解决办法是通过慢速启动的方式解决的。所谓的慢速启动是指客户端先发送一个包,等收到一个ACK时,又发送2个,等收到2个ACK 将发送4个,这样以一个指数趋势增长的速度进行发送,直到找到一个合适的发送速度。
2:避免拥塞:
拥塞避免算法是一种处理丢失分组的方法。
该算法假定由于分组受到损坏引起的丢失是非常少的(远小于1%),因此分组丢失就意味着在源主机和目的主机之间的某处网络上发生了拥塞。有两种分组丢失的指示:发生超时
和接收到重复的确认。如果使用超时作为拥塞指示,则需要使用一个好的RTT算法。
拥塞避免算法和慢启动算法是两个目的不同、独立的算法。但是当拥塞发生时,我们希望降低分组进入网络的传输速率,于是可以调用慢启动来作到这一点。在实际中这两个算法
通常在一起实现。
拥塞避免算法和慢启动算法需要对每个连接维持两个变量:一个拥塞窗口 cwnd和一个慢启动门限ssthresh。这样得到的算法的工作过程如下:
1) 对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。
2) TCP输出例程的输出不能超过 cwnd和接收方通告窗口的大小。拥塞避免是发送方使用的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估
计,而后者则与接收方在该连接上的可用缓存大小有关。
3) 当拥塞发生时(超时或收到重复确认),ssthresh被设置为当前窗口大小的一半( c w n d和接收方通告窗口大小的最小值,但最少为 2个报文段)。此外,如果是超时引起了拥塞,则
cwnd被设置为1个报文段(这就是慢启动)。
4) 当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免。如果 cwnd小于或等于ssthresh,则正在进行慢启动,否则正在进行拥塞避免。
慢启动一直持续到我们回到当拥塞发生时所处位置的半时候才停止(因为我们记录了在步骤 2中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。
慢启动算法初始设置 cwnd为1个报文段,此后每收到一个确认就加 1。这会使窗口按指数方式增长:发送 1个报文段,然后是2个,接着是4个⋯⋯。
拥塞避免算法要求每次收到一个确认时将 cwnd增加1 /cwnd。与慢启动的指数增加比起来,这是一种加性增长(additive increase)。我们希望在一个往返时间内最多为cwnd增加1个报文段(不管在这个RT T中收到了多少个ACK),然而慢启动将根据这个往返时间中所收到的确认的个数增加cwnd。
下图是慢启动和拥塞避免的一个可视化描述。我们以段为单位来显示cwnd和ssthresh,但它们实际上都是以字节为单位进行维护的。
在该图中,假定当cwnd为32个报文段时就会发生拥塞。于是设置 ssthresh为16个报文段,而cwnd为1个报文段。在时刻 0发送了一个报文段,并假定在时刻 1接收到它的 ACK,此时cwnd增加为2。接着发送了2个报文段,并假定在时刻2接收到它们的ACK,于是cwnd增加为4(对每个ACK增加1次)。这种指数增加算法一直进行到在时刻 3和4之间收到8个ACK后cwnd等于ssthresh时才停止,从该时刻起, cwnd以线性方式增加,在每个往返时间内最多增加 1个报文段。
正如我们在这个图中看到的那样,术语“慢启动”并不完全正确。它只是采用了比引起拥塞更慢些的分组传输速率,但在慢启动期间进入网络的分组数增加的速率仍然是在增加的。只有在达到ssthresh拥塞避免算法起作用时,这种增加的速率才会慢下来。
3:快速重传:
TCP规定在接受到三个及以上的重复ACK时,不管是什么原因引起的默认,有数据报的丢失,且不等待超时就立即重传丢失的包。
4:快速恢复:
在执行快速重传不执行慢速启动,而是执行避免拥塞,这就是快速回复。