TCP协议和UDP协议的特点
TCP协议相对于UDP协议的特点是:面向连接、字节流和可靠传输。
这里需要明确一下什么叫字节流,什么叫数据报。
字节流:发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系,发送端和接收端分别与TCP缓冲区交互,应用程序对数据的发送和接收是没有边界限制的。
数据报:发送端应用程序每执行一次写操作,UDP模块就将其封装成一个UDP数据报并发送之。接收端必须及时针对每一个UDP数据报执行读操作,否则就会丢包。并且,如果用户没有指定足够的应用程序缓冲区来读取UDP数据,则UDP数据将被截断。
下面的图能够更加清晰的描述二者的区别。
TCP头部结构
注意:16位窗口大小是TCP流量控制的一个手段。这里的窗口指的是接收通告窗口,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
TCP连接的建立和关闭
处于FIN_WAIT_2状态的客户端需要等待服务器发送结束报文段,才能转移至TIME_WAIT状态,否则它将一直停留在这个状态。连接停留在FIN_WAIT_2状态的情况可能发生在:客户端执行半关闭后,未等服务器关闭连接就强行退出了,此时客户端连接由内核来接管,称为孤儿连接。
TCP拥塞控制
拥塞控制的目的是提高网络利用率,降低丢包率,并保证网络资源对每条数据流的公平性。拥塞控制的四个部分:慢启动、拥塞避免、快速重传、快速恢复。
拥塞控制其实是控制发送端向网络一次连续写入(收到其中第一个数据的确认之前)的数据量,称为SWND(发送窗口)。接收方可通过其接收通告窗口RWND来控制发送端的SWND,但是显然不够,所以发送端引入了一个称为拥塞窗口(CWND)的状态变量。实际的SWND值是RWND和CWND中的较小者。如下图:
慢启动算法的理由是:TCP模块刚开始发送数据时并不知道网络的实际情况,需要用一种试探性的方式平滑地增加CWND的大小。但是刚开始这个CWND的值是以指数形式扩大,如果不进行干预,必然使得CWND很快膨胀,并最终导致网络拥塞。因此TCP拥塞控制中定义了另一个重要的状态变量:慢启动门限,当CWND的大小超过该值时,TCP拥塞控制将进入拥塞避免阶段。
拥塞避免算法使得CWND按照线性方式增加,从而减缓其扩大。
很多情况下,发送端都可能收到重复的确认报文段,比如TCP报文段丢失。拥塞控制算法需要判断当收到重复的确认报文段时,网络是否真的发生了拥塞。具体做法是:发送端如果连续收到3个重复的确认报文段,就认为是拥塞发生了。然后将启用快速重传和快速恢复算法来处理拥塞。过程如下:
1)当收到第3个重复确认报文段时,重新计算慢启动门限值,然后立即重传丢失的报文段,并设置CWND。(重新开始慢启动)
2)每次收到1个重复的确认时,设置CWND,此时发送端可以发送新的TCP报文段。
3)当收到新数据的确认时,设置CWND为新的慢启动门限值。
快速重传和快速恢复完成之后,拥塞控制恢复到拥塞避免阶段。
TCP/IP通信实例逻辑
其中,Kongming20上运行wget客户端程序,ernest-laptop上运行squid代理服务器程序(HTTP代理服务器)。客户端通过代理服务器的中转,获取Internet上的主机www.baidu.com的首页。
HTTP代理服务器的工作原理
正向代理要求客户端自己设置代理服务器的地址。客户的每次请求都将直接发送到该代理服务器,并由代理服务器来请求目标资源。
反向代理则被设置在服务端,因而客户端无需进行任何设置。反向代理是指用代理服务器来接收Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从内部服务器上得到的结果返回给客户端。这种情况下,代理服务器对外就表现为一个真实的服务器。
访问DNS服务器
IP头部的源端IP地址和目的端IP地址在转发过程中是始终不变的,但是帧头部的源端物理地址和目的端物理地址在转发过程中则是一直在变化的,因此在此过程中,在不停的找路由器的mac地址。