Android程序员必知必会的网络通讯传输层协议——UDP和TCP

一、点评

互联网发展至今已经高度发达,而对于互联网应用(尤为即时通信技术这一块)的开发者来讲,网络编程是基础中的基础,只有更好地理解相关基础知识,对于应用层的开发才能作到游刃有余。php

对于Android程序员来讲,若是您以为本文内容稍显枯燥,能够看看即时通信网以前整理过的一篇相似文章《迈向高阶:优秀Android程序员必知必会的网络基础》,该文内容更偏向于知识点的归纳。html

若是您但愿更系统地学习网络编程方面的知识,能够读一读如下专为初学者整理的系列文章或资料:程序员

TCP/IP详解 - 第11章·UDP:用户数据报协议编程

TCP/IP详解 - 第17章·TCP:传输控制协议缓存

TCP/IP详解 - 第18章·TCP链接的创建与终止安全

TCP/IP详解 - 第21章·TCP的超时与重传服务器

网络编程懒人入门(一):快速理解网络通讯协议(上篇)网络

网络编程懒人入门(二):快速理解网络通讯协议(下篇)并发

网络编程懒人入门(三):快速理解TCP协议一篇就够负载均衡

网络编程懒人入门(四):快速理解TCP和UDP的差别

网络编程懒人入门(五):快速理解为何说UDP有时比TCP更有优点

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

网络编程懒人入门(七):深刻浅出,全面理解HTTP协议

网络编程懒人入门(八):手把手教你写基于TCP的Socket长链接

网络编程懒人入门(九):通俗讲解,有了IP地址,为什么还要用MAC地址?

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(二):咱们在读写Socket时,究竟在读写什么?

脑残式网络编程入门(三):HTTP协议必知必会的一些知识

脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

脑残式网络编程入门(五):天天都在用的Ping命令,它究竟是什么?

脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

学习交流:

- 即时通信/推送技术开发交流4群:101279154[推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM

(本文同发布于:http://www.52im.net/thread-2216-1-1.html

二、前言

相信计算机专业的朋友在大学都学过《计算机网络》这门课程,但据我我的了解计算机专业普通大学生对计算机网络的了解浅之又浅,不少人说这门学科没用,开发的时候也用不着,其实这样想是不对的。

说一下我我的的体会,以前总是听别人说OkHttp怎么这么好用,但用完以后感受和其余框架没多大区别啊,因而就想着去专研钻研,当时差很少花了一个星期左右把OkHttp源码看了一遍,代码时看懂了,可是有些地方不知道为何这样作,因此我就下决心把计算机网络从新学一遍,学完各类网络协议后再看OkHttp源码忽然有种面目一新的感受。

在本篇文章里,会为你们讲述做为Android程序员的我,对于网络通讯传输层协议UDP、TCP的理解,但愿能给你带来启发。

参考书籍:《计算机网络-谢希仁版

参考教程:《韩立刚视频教程

三、关于做者

网名:zskingking,博客地址:https://www.jianshu.com/u/274367e58472

四、UDP协议

4.1 概述

UDP的全称是User Date Protocal,翻译成中文是用户数据包协议,它是一种不可靠的传输协议,通常状况下一个数据包(大概64K)能完成的数据通信使用UDP协议,好比请求DNS解析IP地址使用的就是UDP协议,由于解析IP一个数据包彻底足够。还有就是文字聊天通常用的也是UDP,一般一段文字消息一个数据包就足够了,若是发送失败就再次发送,反正就一个数据包。还有一种传递大量数据包使用UDP协议的场景,就是广播,相似对讲机之类的,接收方并不必定能接收到全部的数据包。因此说UDP是一种不可靠的传输协议。

UDP的主要特色:

1)UDP是无链接的,即发送数据以前是不须要创建链接的;

2)UDP使用尽最大努力交付,不保证可靠交付,同时不使用阻塞控制;

3)UDP是面向报文的,UDP没有拥塞控制,很适合多媒体通讯的要求;

4)UDP支持一对1、一对多、多对1、多对多的交互通讯;

5)UDP的首部开销小,只须要8个字节。

4.2 UDP首部

首先咱们先用一张图来表示UDP的首部,UDP首部以下图:

 

UDP首部总共是8个字节,其中源端口、目的端口、长度、检验和各占2字节。有的同窗可能要问了,你怎么没把伪首部加进去呢?这个我来说一下,伪首部顾名思义,就是假的首部,它是不会跟随UDP数据报进行传输的,它存在的意义就是为了计算UDP首部中的检验和。

UDP首部存储的信息:

1)源端口:即发送方的端口号,须要接收方回应时选用,不须要全为0;

2)目的端口:接收方端口号;

3)长度:UDP数据报长度,最小为0(只存在首部);

4)检验和: 检验UDP数据报在传输中是否出错,是就丢弃。

UDP首部组装完毕后会将完整的数据报发送到网络层,跟IP数据报首部组成IP数据报再向上发送。

五、TCP协议

5.1 概述

TCP全称为Transmission Control Protocol(传输控制协议),是一种可靠的面向链接传输协议,同时它也是一种client-server模式的协议,由于是可靠的传输协议,因此它比UDP要复杂的多。

首先说一下TCP具备的一些特性:

1)TCP是面向链接的传输协议;

2)每一条TCP有且只有两个端点,为一对一关系;

3)TCP提供可靠交互的服务;

4)TCP提供全双工通讯,全双工为便可传输又可接收;

5)TCP是面向字节流的。

TCP的应用场景:

若是两个台主机想要在网络上传递一部1G大小的电影,须要经过什么协议进行传输呢?UDP为不可靠传输协议,传递过程当中可能会出现丢包,因此UDP不行,而传输层就两个协议,一个是UDP一个是TCP,UDP传输效率高但不可靠,TCP传输效率低但它是可靠的,因此想要将传递的文件完整的到达目的地能够经过TCP协议进行传输。

5.2 TCP链接创建与断开

在5.1中介绍TCP特性的时候提到,TCP是面向链接的,即TCP在传输数据前要创建链接,数据传输完毕后要断开链接。TCP链接必需要由客户端发起。

【5.2.1】TCP创建链接过程:

 

 

如上图2所示:客户端向服务端发起创建链接的请求,服务端接收到请求后告诉客户端:“我准备好了”,客户端接收到服务端的响应再给服务端一个确认,此过程总共分为三步被你们亲切的成为:“三次握手”,三次握手后一个可靠的链接就创建了,随后就能够进行数据的传输了,图中SYN、ACK这些字段我会在TCP首部中详细介绍,此处你们能够忽略。

疑点: TCP创建链接为何是三次握手?两次握手不是已经能够创建一个链接了吗?网络上不少文章对此处的描述大可能是轻描淡写,还有的说是必需要三次握手才能创建一个可靠链接,其实这样说是不对的,当时我也由于这些不负责任的回答费解了好久。通常状况下,两次握手是能够创建一个TCP链接的,在《计算机网络-谢希仁》中大概是这样解释的:“第三次握手是为了不服务端形成资源的浪费”,为何这样说呢?我来给你们举一个例子:

假如TCP是两次握手:主机A向主机B发送了一个创建链接的请求x,但这个请求在半路里给堵了,主机A没有获得主机B的响应因而又发了一个创建链接的请求y,主机B收到了请求y,因而给主机A发送了一个确认,此时链接创建,数据传输完毕后断开了链接,但在断开链接后堵在半路的请求x到达了主机B,此时主机B认为主机A又给本身发送了一个创建链接的请求,因而给主机A发送了一个确认,此时主机B认为链接已经创建,处于等待状态从而致使主机B资源的浪费。但若是是三次握手就能够避免这种状况的出现,因此这才是TCP第三次握手的缘由。

【5.2.2】TCP断开链接过程:

 

 

如上图所示:主机A至主机B数据传输结束后主机A会向主机B发送一个断开链接请求,主机B收到后给主机A一个确认,A就不可向B传输数据了,但此时主机B仍然能够往主机A传输数据,等B->A数据传输结束后主机B向主机A发送一个断开链接请求。主机A收到后给予一个确认,这样就成功断开一个TCP链接,过程分四步,也被你们亲切的称为:“四次挥手”。

疑点:断开链接为何是四次挥手?两次不就能够了吗?下面我来用一个形象的例子来个你们解除疑点

TCP是全双工的:即client和server均可以进行传输和接收,假设主机A和主机B创建了一个TCP链接,主机A能够往主机B发送数据同时主机B也能够往主机A发送数据,如今我将主机A->主机B描述成一根水管x,水管x只能由A流到B,主机B->主机A为水管y,水管y只能由B流到A,如今水管x已经完成的它的输送水源工做,此时就能够将水管x切除,对应图中前两次挥手,但此时水管y还在工做,必需要等水管y工做完成后才可以将其切除,切除水管y对应图中后两次挥手。

5.3 TCP首部

首先用一张图来表示TCP首部的构造,TCP首部以下图所示:

 

TCP首部的各项内容解释:

1)源端口:发送方端口号;

2)目的端口:接收方端口;

3)序号:数据包的序号,以数据包第一个字节进行表示;

4)确认号:确认收到数据包的序号,一样以字节进行标识;

5)数据偏移:TCP首部长度,以字节为单位;

6)保留:保留位,总共6为,必须都为0;

7)URG:紧急处理,可提高数据包发送的优先级;

8)ACK:表明确认号是否有效;

9)RST:将创建的链接重置;

10)PSH:接收方应尽快将这个报文交给应用层;

11)SYN:同步序号用来发起一个链接;

12)FIN:终止一个链接。

本小节只是让你们对TCP首部有一个概念性的认识,因此你可能会对首部中某些字段不太理解,不要紧,在下面的文章中我还会提到这些字段。

5.4 TCP进行可靠传输

咱们知道网络传输是不可靠的,可能存在丢包的现象,TCP是可靠的传输协议,那么它是怎么作到可靠传输呢?我来用几张图为你们分析TCP师怎样进行可靠传输的。

以下图所示:

 

状况a:A发送给B数据包M1,B收到以后进行确认,这样M1包就发送成功了,以此类推,这是无差错的状况。

状况b:A发送数据包M1给B,但中途被丢弃了,若是A迟迟等不到B的响应那么A就会从新发送M1包给B。

以下图所示:

 

状况a:A发送数据包M1给B,B收到后给A发送一个M1的确认包但该确认包在中途被丢弃了,A迟迟未收到B的确认包就认为M1发送包或者M1确认包早中途丢失了,因而又发送了一个M1包给B,B又收到了一个M1包,此时B就能够认为M1确认包可能在中途丢失了,将重复的M1包丢弃后再给A发送一个M1确认包;

状况b:A发送数据包M1给B,B收到后给A发送一个M1确认包,但该确认包选择了一个较远的传输路线或者被阻塞了,A迟迟未收到M1确认包就再给B发送一个M1包,B收到重复的M1包后将其丢弃而后再给A发送一个M1确认包,A收到M1确认后就认为M1发送成功,但此时A收到半路阻塞的那个M1确认包,而A已经确认了M1包发送成功,因此再次受到M1确认包后什么也不作。

client-server能够经过传递确认的方式来实现可靠传输,但这种传输方式有一个缺点,效率过低,由于在未收到确认包前是不能够发送下一个包的,那么咱们能不能突破这一限制来提高传输效率呢?咱们能够经过提高信道的利用率来提高传输效率,以下图所示:

 

从上图咱们能够看到,A在未收到B确认前发送了10个数据包,在这我就将10个数据包形象的编号为1-10,A一次发送10个数据包,当B收到数据包1的时候给A一个确认,A收到确认后再发送数据包11,当B收到数据包2的时候给A一个确认,A收到确认后再发送数据包12,以此类推。

上图中A最多一次能够连续发送10个数据包,而这个10咱们可不能够理解为一个窗口呢?打个比方,如今有一个窗口共有10个格子,每一个格子放一个数据包,发送的数据包放在格子里面,当收到第一个数据包的确认包后将该数据包从窗口中移出,而后将须要发送的下一个数据包放入窗口。

咱们这里提到的窗口就是TCP首部里面说的那个窗口,下面我结合图给你们分析一遍:

 

上图中,如今咱们有12个数据包须要发送,窗口大小为5,因此最多一次可连续发送5个数据包,假设如今窗口中的五个数据包都已经发送完毕,此时收到了数据包1的确认包,那么绿色窗口就能够往右边移一个格子,以下图:

 

上图中,数据包6被滑进格子里,此时数据包6就能够被发送,同时数据包1也能够从缓存中清除,经过这种方式能够提高信道的利用率从而提高传输效率,但这种传输方式也有一个缺点,就是接收方每收到一个数据包都要进行一次确认,这是彻底不必的,咱们可不能够这样作:每收到5个数据包进行一个确认,以下图:

 

A一次给B发送了5个数据包,B确认5个数据包都收到了,给A回复一个6,表明B已经收到了前5个数据包让A下次从第6个数据包开始发送,经过累积响应这种方式又进一步提高了传输效率,但这是理想状况下,若是说A发送完5个数据包,B只收到了一、二、四、5,数据包3丢了,怎么办?是直接给A回复一个3吗?是的话四、5都要进行重传,这样就得不偿失了,而编写TCP协议那位老哥也想到了这种状况,因此就指定了相应的策略,接着刚刚说,若是B肯定数据包3丢了或者被阻塞了,那么它会马上连续发送3个3,A收到连续的3个3后就认为数据包3丢了,而后就会只补传数据包3。

注意点:

上面的内容中我为了方便讲解都是把数据包编成编号进行描述,其实真正的数据包编号不是这样的,TCP协议是面向字节流的,因此说序号和确认号应以字节为标准,好比:A如今向B发送了5和数据包共100个字节,B收到这5个数据包后会给A回复一个101,此时A就会从第101个字节开始进行发送,以此类推。同时经过这种机制也能够实现断点的下载。

5.5 流量控制

流量控制:用来协调server和client两端因处理数据速度不一样所带来的问题。

举个例子:

假如主机A要向主机B发送数据,若是主机A发送数据的速度比主机B处理数据的速度要快,那么极可能致使主机B崩溃,经过TCP流量控制技术能够调整主机A发送数据的速度从而解决上面的问题。

TCP是怎样实现流量控制的的?首先说明一点,前面咱们描述TCP传输数据的时候提到了滑动窗口这个概念,其实不光发送方存在滑动窗口,一样接收方也存在滑动窗口,接收方收到数据包后会将数据包放入滑动窗口,对数据包操做完毕后将该数据包从滑动窗口中移出,当滑动窗口被填满时不能够再接收数据,TCP中发送发窗口和接收方窗口大小是相同的。

因此,经过滑动窗口机制能够实现流量控制,以下图所示:

 

上图中,B为发送方A为接收方,当B与A创建链接的时候首先会明确本身滑动窗口的大小,假如是10,B就会将rwnd(滑动窗口)设置为10,A收到后也会将滑动窗口设置为10,链接创建成功会A开始向B发送数据,咱们知道滑动窗口越大发送的速度越快,假如rwnd=10时B处理数据包的速度小于接收数据包的速度那么滑动窗口会逐渐被填满,这样会致使主机B中未处理的数据包愈来愈多最终可能会崩溃,为了不这种状况的出现,B能够在滑动窗口被填满了以后给A发送一个rwnd=6,A接收到rwnd=6后会将滑动窗口调整为6进而下降发送数据的速度,一样B若是以为A的发送速度过慢也能够经过设置rwnd的值来调整A的发送速度,B动态的设置A的滑动窗口就称做为TCP流量控制技术。

5.6 拥塞避免

什么是拥塞呢?顾名思义就是赌了,数据被堵在半路了,那什么状况下会出现数据被堵在半路呢?

举个例子:

假如现有两台主机分别是发送方主机A和接收方主机B,主机B的带宽为50M/S,也就是说主机B每秒最多能接收50M的数据,若是主机A的发送速度远低于50M/S,这种状况应该是不会出现拥塞现象的,可是若是主机A的发送速度远大于50M/S,主机B的路由器接手不了这么多数据只能进行丢弃,路由器也是有CPU、内存和本身的操做系统,当主句A发送速度越快主机B的路由器CPU和内存就要分配更多的资源去处理丢弃数据包,这样就会致使接收数据包的速度愈来愈低,极端的状况下可能会出现主机B接收不到数据包的现象,也就是死锁现象。

若是在进行TCP数据传输的时候不进行流量控制很容易出现死锁现象,由于网络是你们共用的,因此避免网络拥塞现象的出现须要全部计算机遵照一种特定的规则,那这种规则是怎样控制网络避免拥塞的呢?

先来看下面这张图:

 

若是不进行拥塞控制就是咱们上面所说的,最终可能会出现上图中绿线的状况,如今咱们要经过拥塞控制使网络数据传输按照上图中蓝线进行。

下面咱们来讲一下如何进行拥塞控制:

 

首先将滑动窗口设置为1,而后再传输过程当中逐渐以指数倍增长,当滑动窗口到达ssthresh的时候再以加法进行增长,若是出现了拥塞现象就迅速再将滑动窗口设置为1,ssthresh减少依次循环,这种方式也称为慢开始方式。但这种方式已经被废弃,由于每次出现拥塞的时候都会将滑动窗口设置为0再进行慢开始阶段,这样实际上是彻底不必的。

咱们再来看升级版,以下图:

 

在出现拥塞的时候并不会将滑动窗口设置为1从新进行慢开始,而是将滑动窗口设置为出现拥塞时窗口的一半,而后再以加法进行增长,此过程也可称为是快恢复,这样就能够避免网络拥塞的出现。

附录:更多网络编程文章

技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

通俗易懂-深刻理解TCP协议(上):理论基础

通俗易懂-深刻理解TCP协议(下):RTT、滑动窗口、拥塞处理

理论经典:TCP协议的3次握手与4次挥手过程详解

理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程

计算机网络通信协议关系图(中文珍藏版)

UDP中一个包的大小最大能多大?

P2P技术详解(一):NAT详解——详细原理、P2P简介

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

P2P技术详解(三):P2P技术之STUN、TURN、ICE详解

通俗易懂:快速理解P2P技术中的NAT穿透原理

高性能网络编程(一):单台服务器并发TCP链接数到底能够有多少

高性能网络编程(二):上一个10年,著名的C10K并发链接问题

高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索

高性能网络编程(五):一文读懂高性能网络编程中的I/O模型

高性能网络编程(六):一文读懂高性能网络编程中的线程模型

鲜为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)

鲜为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)

鲜为人知的网络编程(三):关闭TCP链接时为何会TIME_WAIT、CLOSE_WAIT

鲜为人知的网络编程(四):深刻研究分析TCP的异常关闭

鲜为人知的网络编程(五):UDP的链接性和负载均衡

鲜为人知的网络编程(六):深刻地理解UDP协议并用好它

鲜为人知的网络编程(七):如何让不可靠的UDP变的可靠?

技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解

让互联网更快:新一代QUIC协议在腾讯的技术实践分享

现代移动端网络短链接的优化手段总结:请求速度、弱网适应、安全保障

聊聊iOS中网络编程长链接的那些事

移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”

移动端IM开发者必读(二):史上最全移动弱网络优化方法总结

IPv6技术详解:基本概念、应用现状、技术实践(上篇)

IPv6技术详解:基本概念、应用现状、技术实践(下篇)

从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

以网游服务端的网络接入层设计为例,理解实时通讯的技术挑战

迈向高阶:优秀Android程序员必知必会的网络基础

全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等

美图App的移动端DNS优化实践:HTTPS请求耗时减少近半

Android程序员必知必会的网络通讯传输层协议——UDP和TCP

>> 更多同类文章 ……

(本文同发布于:http://www.52im.net/thread-2216-1-1.html

相关文章
相关标签/搜索