TCP与UDP基本区别
- 基于连接与无连接
- TCP要求系统资源较多,UDP较少;
- UDP程序结构较简单
- 流模式(TCP)与数据报模式(UDP);
- TCP保证数据正确性,UDP可能丢包
- TCP保证数据顺序,UDP不保证
UDP应用场景:
- 面向数据报方式
- 网络数据大多为短消息
- 拥有大量Client
- 对数据安全性无特殊要求
- 网络负担非常重,但对响应速度要求高
TCP报头
UDP报头
TCP三次握手
- TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
- TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
- TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
- TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
- 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么TCP客户端最后还要发送一次确认呢?
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
TCP四次挥手
- 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
- 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
- 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
- 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间 后,当客户端撤销相应的TCB后,才进入CLOSED状态。
- 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
为什么客户端最后还要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
总的来说 TCP协议提供可靠的服务, UDP协议提供高效率的服务。
高可靠性的TCP服务提供面向连接的服务,主要用于一次传输大量报文的情形, 如文件传输,远程登录等;
高效率的UDP协议提供无连接的数据报服务,用于一次传输少量的报文。 即使发生传输错误,也可以重新传输并且不会为此付出多少代价。
TCP提供的是面向连接的、可靠的数据流传输,可避免数据传输错误。 面向连接的协议在任何数据传输前就建立好了点到点的连接。
而UDP提供的是非面向连接的、不可靠的数据流传输。当一个UDP数据包在网络中移动时, 发送过程并不知道它是否到达了目的地,除非应用层已经确认了它已到达的事实。 当数据传输的性能必须让位于数据传输的 完整性、 可控制性 可靠性时, TCP协议是当然的选择。 当强调传输性能而不是传输的完整性时, 如:音频和多媒体应用, UDP是最好的选择。 在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下 UDP也是一个好的选择 ,如:DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时, UDP较低的开销使其有更好的机会去传送管理数据。
总结
tcp 提供可靠的服务 若强调 完整性 可靠性可控性 选择tcp
udp 提供高效的服务 若强调 传输性能 选择udp
TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、 用于传输大量数据(流模式)、速度慢,建立连接需要开销较多 (时间,系统资源)。 UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
- tcp和udp的区别,简单来说, tcp是有序可靠传输, 而udp是不可靠乱序传输,但是实际上你把udp看做IP可能更准确一点,因为可以在udp基础上开发出可靠udp等各种传输.
- tcp的优缺点是什么?优点,这是一个国际通行了很多年的标准实现,调用简单,省心,很多应用都基于tcp进行实现的,最关键的是,它的兼容性是跨平台的,也就是,只要你选择的是tcp,那么不管是windows还是linux,unix,只要支持tcp/ip,那么就可以保证实现可靠连接和传输.作为软件的开发者只需要考虑应用层,比如应用协议等的实现就可以了. 至于可靠传输的性能,由于是国际标准,在内核层实现和运行,很多都做了硬件级的优化,因此对比起用udp等实现的可靠传输,本机[注意是本机]的极限传输性能要高很多.
那么tcp有什么明显的缺点呢? 对开发者来说最头大的恐怕就是2条, 第一是每个tcp连接都是1对1连接,这意味着每个连接都需要一个套接字socket,并且需要随时测试是否数据可读可写.当连接数量达到一定的程度,性能会直线下降. 没有经历过大规模并发应用开发的朋友可能很难想像,就一个基本没有数据的空连接怎么会消耗系统的性能呢?其实这个问题,不可以单纯从硬件或者api接口等进行解释,而需要从tcp/ip协议栈的实现中去发现的,从可以查看到的代码,Linux freebsd unix来看,无一列外,在操作系统里使用的是指针链表进行管理, 重要的事情说3遍 , 用的是指针链表 ,指针链表,指针链表 , 看下Linux 下的实现 [不是最新版,不过这个应该不会改变,因为会导致整个代码重构] ,
ip层的接收
for( qp=ipqueue; qp!=NULL; qplast=qp,qp=qp->next) { if(iph->id==qp->iph->id && ....... }
新版本4的测试版Linux核心tcp/ip实现, 和之前的比,是使用了rcu_函数来优化,其实换汤不换药,在执行插入和写操作的时候,需要执行rcu_writelock, 这和readlock不同,能且只有一个锁定,而无法多重锁定,性能在这里遇到了瓶颈, 这个瓶颈出现在tcp/ip协议栈的实现中,由于tcp包的构成问题,至少到目前,或者可以遇见的将来,tcp这个严重影响并发性能的问题会一直存在在实现中,这是绝大部分人都始终没有搞明白,为什么tcp在面对海量并发的时候,在超过一定数字后性能出现直线下降的其中一个关键原因. [我曾经尝试过为Linux下Tcp/ip栈的指针链表引入排序等优化,但是经过各种测试,我发现事实上这个实现在大部分情况下性能比排序好,因为排序等反而导致了性能下降,因此除非有革命性的优化出现,目前这个瓶颈会一直存在.]
给出我们自己编写的延迟测试结果 硬件是Intel i3 2350 [2.3g] ddr3 1333 , tcp 连接数量大并频繁小包传输下,协议栈导致延迟非常明显,
看出问题在那里了吗?是个指针遍历操作 , 独占模式 ,一万空连接在目前的cpu前,可能没什么 ,但是如果是并发模式n万小包呢, 那开销n/2......,你再多的cpu核心也没用,一个链表只有一个独占模式的遍历操作,其他cpu只能干着急。
所以在面对小数据量海量长时间连接的应用时,选择tcp必须要慎重再慎重. 第二个大问题是tcp是双向流传输,而keepalive这个功能并非普遍支持, 双向流传输意味着,数据是采用流模式过来的,如果切割取决于协议的制定者,例如普遍的采用\r\n作为分割字符, 而keepalive的非普遍实现,则导致另外一个问题,那就是每个连接,必须每过一定时间在应用协议层检测连接是否还存活,最典型的就是ftp,如果没有指令操作,那么客户端每过一定时间必须发送一条指令,通常是noop指令给服务器端,告诉服务器,我还保持着连接,不要中断.
可能有人无法理解,tcp不是可靠连接吗? tcp是可靠连接,要命的时,当tcp建立连接后,如果双方没有应用层的数据传输,那么当物理中断发生的时候,等待的一方是接收不到发生故障的一方的任何消息的,直到没有发生故障的一方,主动发送数据给另一方,出现发送超时的时候,才能给出中断判断,否则就是个死等待,这就是ftp等协议中引入noop等类似机制的原因. 流传输的另一个问题是,无法实现数据的并发传输,而只等排队发送,这在很多应用,特别是游戏类应用是严重的缺陷,无论你有多着急,一个连接就是一个流,你要排队先发送到缓冲,然后由系统负责发送缓冲数据,可能有人说可以使用紧急指针带外数据,但这玩意不是让你用来传输数据的,其实是让你用来发送紧急通知用的,在tcp中使用带外数据,除了带来更复杂的实现,没有什么实质性作用,以ftp为例子,实际上无论你使用使用紧急指针带外数据,都可以中断数据传输的,这个紧急指针在那里除了保持兼容性,没有实际作用.
- udp的优缺点是什么? udp是比tcp更接近IP的协议, 通常udp是不可靠传输,但是我们可以在应用层对udp加上校验和序列号,做成可靠传输,这一点不可不知. udp的优点是什么? 书上总是说udp的性能比tcp好,有没有人想过为什么? 其实原因很简单, udp是发射后不管, 不需要对方发送ack包进行确认, tcp由于需要对每一个包进行ack确认,一来一回,就会影响到传输效率,但事实上,这个影响是很小的,如果不考虑丢包和线路不稳定等,这个差距一般只有百分只几,除非你做极限测试. 但实际上,真正用到udp高效传输的场合是非常少的,一个关键的原因在于它的不可靠性,特别是在Internent上,遇到网关路由高负载的时候,优先扔掉udp包,而且有几率发生连续的丢包. 我个人认为,udp最大的优点在于它的可塑性非常强, 我们可以通过各种机制来改造udp,例如实现可靠传输,实现1对多传输, 实现包和流模式同时传输,优先发送,多路双向传输等等, 很多扩展在tcp上是无法实现的,但是通过udp扩展就可以很轻松的做到.同样,通过扩展udp来实现可靠传输,我们可以避开tcp/ip协议栈实现中指针链表查询导致的性能急剧下降,很多人都没有意识到这点,其实在应对海量连接方面,udp可靠传输能支持的用户数量远超tcp,因为udp不需要那种大规模的链表查询,是个队列操作. 那么udp的缺点是什么,最要命的就是不可靠传输,其次是包的伪造,虽然我们可以通过加入各种机制和扩展,把udp改造成可靠传输,但是由于这个实现是在应用层,因此在面对少量用户大流量传输的时候,极限输出不如tcp,例如本机.
那么如何选择tcp还是udp?
先看下人家怎么选
- HTTP, http协议现在已经深入影响到我们的方方面面,重要性就不说了, 它采用的是tcp 协议,为什么使用tcp, 因为它传输的内容是不可以出现丢失,乱序等各种错误的,其次它需要跨平台实现,而tcp满足了这个要求,发展到今天,http享受了tcp带来的简洁高效和跨平台,但是也承受了tcp的各种缺点,例如缺少tcp keep alive机制[这个其实是后来添加的支持,并非普遍实现], tcp协议栈的实现问题引发的难以支持海量用户并发连接[只能通过dns等级别的集群或者cdn来实现],协议太复杂导致很难模块化处理[其实这个问题已经在nginx解决了,nginx通过模块化和对协议的分段处理机制,并引入消息机制,避免了多进程[线程]的频繁切换,相比apache等老牌web服务器软件,在应对大量用户上拥有极大的优势。 即使站在今天的角度看,http也确实应该选择tcp.
- FTP, 这个协议比http更加古老,它采用的也是tcp协议, 因为它的每一个指令,或者文件传输的数据流,都需要保证可靠性,同时要求在各种平台上广泛支持,那么就只能选择tcp, 和http不同,它采用了noop指令机制来处理tcp缺少keep alive机制带来的问题,也就是客户端必须每过一段时间,如果没有发送其他指令,就必须发送一个noop指令给服务器,避免被服务器认为是死连接。 Ftp的缺陷在哪里呢?,其次它的文件传输是采用新的数据连接来执行,等于1个用户需要2个连接,其次当一个文件正在传输的时候,你无法进行其他操作,例如列表,也许你可以把它当作是一一对应的典范,因为这样我们可以直接用命令行进行控制,但是很多用户其实是需要在下载的时候同时进行列表等操作的,为了解决这个问题,很多客户端只要开启多个指令连接[和数据连接],这样一来,无形中额外带给了Ftp服务器很多压力,而采用udp可靠传输就不存在这个问题,但是udp可靠传输是没有跨平台支持的,这样是鱼和熊掌不可兼得,对于这样一个简单的开放协议的实现,tcp是个好选择。
- POP3/SMTP, 常见的邮件协议,没什么好说的,反应--应答模式,跨平台要求,因此tcp是个选择,这个协议的悲剧在于,当初没有考虑到邮件附件会越来越大的问题,因此它的实现中将附件文件采用了base64编码格式,用文本模式进行发送,导致产生了大量的额外流量。
- TFTP ,这是一个非常古老的用于内部传输小文件的协议,没有FTP那么多功能,采用的是udp协议,通过在包中加入包头信息,用尽可能简单的代码来实现小文件传输,注意是小文件,是一个值得参考的udp改造应用范例.
- 通常的voip,实时视频流等,通常会采用udp协议,这是以内这些应用可以允许丢包,很多人可能认为是udp的高效率所以才在这方面有广泛应用,这我不敢苟同,我个人认为,之所以采用udp,是因为这些传输允许丢包,这是一个最大的前提
那么现在来归纳一下
[1] 如果数据要求完整,不允许任何错误发生
[A] 应用层协议开放模式 [例如http ftp]
建议选择tcp,几乎是唯一选择.
[B] 应用曾协议封闭模式 [例如游戏]
(1) 大量连接
[a] 长连接
[一] 少量数据传输
优先考虑可靠udp传输 , tcp建议在20000连接以下使用.
[二] 大流量数据传输
只有在10000连接以下可以考虑tcp , 其他情况优先使用udp可靠传输
[b] 短连接
[一] 少量数据传输
建议使用udp标准模式, 加入序列号, 如果连接上限不超2万,可以考虑tcp
[二] 大流量数据传输
10000连接以下考虑tcp ,其他情况使用udp可靠传输
在遇到海量连接的情况下,建议优先考虑udp可靠传输,使用tcp,由于tcp/ip栈的链表实现的影响,连接越多,性能下降越快,而udp可以实现队列,是一条平滑的直线,几乎没有性能影响.
(2) 有限连接 [通常小于2000 , 一般每服务器为几百到1000左右]
[a] 长连接
除非有数据的实时性要求,优先考虑tcp,否则使用udp可靠传输.
[b] 短连接
优先考虑tcp.
在有限连接的情况下,使用tcp可以减少代码的复杂性,增加广泛的移植性,并且不需要考虑性能问题.
[2] 允许丢包,甚至可以乱序
[a] 对实时性要求比较高,例如voip , 那么udp是最优选择.
[b] 部分数据允许丢包,部分数据要求完整,部分有实时性要求,通常这样的需求是出现在游戏里, 这时候, 基于udp协议改造的udp多路可靠传输[同时支持不可靠模式],基本是唯一能满足的,当然也可以使用tcp来传输要求完整的数据,但是通常不建议,因为同时使用tcp和udp传输数据,会导致代码臃肿复杂度增加,udp可靠传输完全可以替代tcp.
[c]部分数据优先传输,部分可丢弃数据在规定时效内传输, 这通常是实时视频流, 在有限连接模式下,可以考虑tcp+udp , 但是通常, 可靠udp传输是最好的选择.
最后的话, tcp/ip协议很伟大, 在这些基础上诞生了很多划时代的应用,但是时代在发展,需求也在改变,几十年前诞生的基础协议,也遇到了各种问题,典型的是32位地址编码问题,虽然通过nat等技术尽可能的支持更多的机器接入,但是很多应用被限制了,由于tcp/ip协议的巨大影响和事实的上的垄断,导致后续的更新必须考虑到完全兼容, ipv6出现了, 它继承了ipv4的几乎所有优点和缺点,只为了一个字,兼容. 我们可以拥有更快的cpu , 内存, 更强大的tcp/ip系统调用api,但是比较遗憾,tcp/ip协议栈的实现,我们始终无法绕开指针链表, 而正是这,导致了tcp模式在面对海量连接的时候,超过一定数量,网络io性能直线下降, 许许多多的工程师始终认为是cpu 内存不够导致,却没有想到是tcp协议栈的实现上存在性能瓶颈. 在目前的情况下,也只有udp能避开这个协议栈的性能瓶颈,为什么? 因为udp采用的是1对多的虚拟连接, 例如,当虚拟[或者实际]通过udp构建的连接数量是1万个的时候,实际上在协议栈增加的单元只有1个, 而同样1万个连接,tcp增加的单元是1万个,每个片的到达平均要查询5千次,而可靠udp采用队列模式,查询次数是1, 因此, 在今天, 如果你希望你的每台服务器能支持更多的连接,除非你的应用协议需要开放或者兼容其他应用,否则尽可能考虑采用udp, 而不是tcp.
TCP 与 UDP 的区别及应用场景
概述 两者都是通信协议, TCP、UDP 是传输层协议,但他们的通信机制与应用场景不同,下面来阐述两者的区别以及它们的应用场景。
TCP 与 UDP
TCP(Transmission Control Protocol),又叫传输控制协议,UDP(User Datagram Protocol),又叫用户数据报协议,它们都是传输层的协议,但两者的机制不同,它们的区别如下:
特点 TCP UDP 连接性 面向连接 面向非连接 可靠性 可靠 不可靠 传输效率 慢 快
TCP
从如上表格看到,TCP 是面向连接的,并且是一种可靠的协议,在基于 TCP 进行通信时,通信双方需要先建立一个 TCP 连接,建立连接需要经过三次握手,握手成功才可以进行通信,关于 TCP 三次握手、四次挥手的过程请看该文章。 另外 TCP 协议是一种可靠的传输协议,那么它是如何保证可靠性的呢?
可靠性
在讲解 TCP 如何保证可靠性前,首先得理解什么是可靠。在通信的角度来看,可靠即要确保通信双方的通信信息不会丢失,若丢失了保证能够对其进行恢复,并且收到的信息内容与原发送内容一样。
在 TCP 中,传输报文都是通过建立的虚拟连接来进行传输,发送端传输的每一个 TCP 报文,都会对其进行编号(编号是由于网络传输的原因,发送的报文可能会乱序到达,因此需要根据编号对报文进行重排),并且开启一个计时器;当接收端收到报文后,并且通过校验和对收到的报文数据进行校验,若校验成功则会返回一个确认报文,告知发送端我已经成功收到该报文了;若发送端在计时器结束前仍未收到确认报文,则认为接收端接收失败,则会重传该报文;服务端若收到重复报文(根据编号发现已经是收到了),则会将该报文丢弃。
因此,从上面的机制可以知道,TCP 是通过重传、确认和校验和的方式来确保可靠。 注:校验和并不能检验数据是否被篡改过,想要保证数据的完整性可以了解一下数字签名
UDP
UDP 是一种面向无连接,且不可靠的协议,在通信过程中,它并不像 TCP 那样需要先建立一个连接,只要(目的地址,端口号,源地址,端口号)确定了,就可以直接发送信息报文,并且不需要确保服务端一定能收到或收到完整的数据。它仅仅提供了校验和机制来保障一个报文是否完整,若校验失败,则直接丢弃报文,不做任何处理。
TCP 与 UDP 的应用场景
从特点上我们已经知道,TCP 是可靠的但传输速度慢 ,UDP 是不可靠的但传输速度快。因此在选用具体协议通信时,应该根据通信数据的要求而决定。
若通信数据完整性需让位与通信实时性,则应该选用 TCP 协议(如文件传输、重要状态的更新等);反之,则使用 UDP 协议(如视频传输、实时通信等)。
一般面试官都会问TCP和UDP的区别,这个很好回答啊,TCP面向连接,可靠,基于字节流,而UDP不面向连接,不可靠,基于数据报。对于连接而言呢,其实真正的就不存在,TCP面向连接只不过三次握手在客户端和服务端之间初始化好了序列号。只要满足TCP的四元组+序列号,那客户端和服务端之间发送的消息就有效,可以正常接收。虽然说TCP可靠,但是可靠的背后却是lol无尽之刃的复杂和痛苦,滑动窗口,拥塞避免,四个超时定时器,还有什么慢启动啊,快恢复,快重传啊这里推荐大家看看(图解TCP/IP,这个简单容易,TCP卷123,大量的文字描述真是烦),所以什么都是相对呢,可靠性的实现也让TCP变的复杂,在网络的状况很差的时候,TCP的优势会变成。基于字节流什么意思呢?一句话就可以说明白,对于读写没有相对应的次数。UDP基于数据报就是每对应一个发,就要对应一个收。而TCP无所谓啊,现在应该懂了吧。对于UDP而言,不面向连接,不可靠,没有三次握手,我给你发送数据之前,不需要知道你在不在,不要你的同意,我只管把数据发送出去至于你收到不收到,从来和我没有半毛钱的关系。
对于可靠不可靠而言,没有绝对的说法,TCP可靠仅仅是在传输层实现了可靠,我也可以让UDP可靠啊,那么就要向上封装,在应该层实现可靠性。因此很多公司都不是直接用TCP和UDP,都是经过封装,满足业务的需要而已。说到这里的话,那就在提一下心跳包,在linux下有keep-alive系统自带的,但是默认时间很长,如果让想使用话可以setsockopt设置,我也可以在应用层实现一个简单心跳包,上次自己多开了一个线程来处理,还是包头解决。
上面解释完这个之后面试官可能问,那什么时候用TCP,什么时候用UDP呢?就是问应用场景,所以简历上的知识点自己应该提前做好准备应用场景,知识就是要用在显示场景中,废话真多。不管用TCP和UDP,应用只要看需求,对于TCP更加注重的是可靠性,而不是实时性,如果我发送的数据很重要一点也不能出错,有延迟无所谓的话,那就TCP啊。UDP更加注重是速度快,也就是实时性,对于可靠性要求不那么高,所以像斗鱼,熊猫这些在线直播网站应该在UDP基础是封装了其他协议,比如视频实时传输协议。而且UDP的支持多播,那就很符合这些直播网站了,有时候看直播视频卡顿,人飘逸那可能就是丢包了,但是你也只能往下看。