1.UDP协议
UDP协议是传输层的一个不可靠的协议。之前看过物理层、连接层、网络层的协议。Vamei大神的比喻很好,说UDP是IP协议在传输层的傀儡,之所以存在的必要时IP协议不包括端口号,而UDP和TCP都是包括端口号。
端口号是应用程序的资源,不同的应用程序可以占用不同的端口号。程序运行时,操作系统内核从不同端口号获取的消息就提供给占用相应端口号的程序处理。
Vamei大神把网络协议比喻成协议森林我觉得很恰当。连接层协议如以太网、WiFi、ARP协议比喻为树根;IP协议比喻成树干;UDP或TCP等传输层协议比喻为树枝,应用层协议如HTTP比喻成树叶。
数据产生时是从上到下一层一层封装,而解析时是从下到上一层一层拆封。至于每一层封装的格式就是协议的格式,主要包括协议头和数据。
另外大名鼎鼎的soket就是交给内核封装数据的应用。我们在使用soket编写程序时只用提供IP、端口和数据等参数即可。
2.TCP协议
TCP和UDP最大的不同就是TCP是负责任的传输协议。UDP发送数据是以数据报的形式发送,TCP发送数据的方式是流方式。
数据报模式就是数据发送过去,接收端接收数据报。如果属于同一发送端发送的数据报的一部分,则接收端读取、等待接收到全部数据后排序识别。
流模式大多数都把它比喻成自来水管或蓄水池。意思是数据按顺序进行收发,这样就很严格了。这就可以提到段“segment”的概念。假设TCP数据量很大,可以划分为好多段进行传输。那么发送过程为:第一段---->ACK---->第二段---->ACK。ACK是接收端接收到第一段发的确认信息,并要求发送第二段。如果没有收到ACK那么就会重发这一段。所以这是通信双方的严格规定,只有收到才进行下一步,否则就重发。这样是很严格,是很规范,是很容易理解,但却很影响效率。因为一次处理一段就会有大量时间网络处于空闲期。这种单线的工作方式虽然可靠,但是工作效率不高。我们为什么不可以一次发多个段呢?
是,我们可以一次发多个段。但是这些段到达的顺序我们就无法保证了。TCP采用了滑窗的方法解决这个问题。滑窗有几个注意点:
a.滑窗是数据段从头到尾滑的
b.滑窗是有大小的,通常可以容纳几个数据段
c.在发送端的滑窗内的数据段可以同时发送,也可以不按顺序的接受返回的ACK,但是只有滑窗左侧第一个接收到ACK后,滑窗才向右滑动。(那么滑窗左侧的都是按顺序接收到ACK的段,右侧就是还未发送的段)
d.接收端的滑窗可以接收滑窗内的相关段,但是只有滑窗内最左的段接收后,滑窗才会向右移动。
注:滑窗的提出是为了提高TCP的传输效率,我这样简单的描述只是感官上是这样,滑窗是也可以动态变化的。另外接收端接收数据是存放到缓冲区中(蓄水池)。
UDP是面向无连接的,而TCP是面向连接的。接下来就要讲述TCP的连接和终止连接。TCP连接时通常称为三次握手,而终止连接时分为4次握手。
TCP分为头和数据,其中头包括端口号和序号。其中序号的起始值是随机分配的,因为如果选用确定的容易接收到伪TCP段。而建立连接时需要把自己的序号告诉对方。这牵涉到两个段SYN段和ACK段。SYN段就是发送自己的序号,ACK段就是收到确认。连接过程就如下:
A端发送SYN段---->
B端回复ACK段,但同时将ACK段附在B端发送的SYN段---->
A端回复ACK段---->
TCP终止连接分为四步,用到的段为FIN和ACK段。
A端终止连接FIN----->
B端发送ACK段----->
B端终止连接FIN---->
A端发送ACK段---->
为什么步骤二和三不合并?因为关闭连接是一套。而之前连接时整体时一套。TCP连接是双向连接,即A发送数据给B,B发送数据给A。这是两个连接。允许单向连接意味着可以A终止连接而B保持连接。那么只用执行第一、第二步即可。连接时因为在传输过程中要相互发所以A建立连接,B也必须建立连接,进而中间整合一步。而当A觉得我没什么发的,就可以擅自终止自己单方向的连接了。