tcp协议和udp各有什么特点(什么情况下适合用UDP协议)
tcp协议和udp各有什么特点(什么情况下适合用UDP协议)如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。1.TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态; 2.TCP客户进程也是先创建传输控制块TCB,然后向
TCP与UDP基本区别
- 基于连接与无连接
- tcp要求系统资源较多,UDP较少;
- UDP程序结构较简单
- 流模式(TCP)与数据报模式(UDP);
- TCP保证数据正确性,UDP可能丢包
- TCP保证数据顺序,UDP不保证
UDP应用场景:
- 面向数据报方式
- 网络数据大多为短消息
- 拥有大量Client
- 对数据安全性无特殊要求
- 网络负担非常重,但对响应速度要求高
UDP报头
TCP三次握手
1.TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态; 2.TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。 3.TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x 1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。 4.TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y 1,自己的序列号seq=x 1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。 5.当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么TCP客户端最后还要发送一次确认呢?
一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
TCP四次挥手
1.客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2.服务器收到连接释放报文,发出确认报文,ACK=1,ack=u 1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3.客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
4.服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u 1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w 1,而自己的序列号是seq=u 1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
5.服务器只要收到了客户端发出的确认,立即进入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一般都会分开发送,从而导致多了一次。
相关视频推荐:
《tcpip详解卷一》:150行代码拉开协议栈实现的篇章
腾讯一面题: UDP如何实现可靠性传输?
学习地址:C/C Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
需要C/C Linux服务器架构师学习资料加群812855908获取(资料包括C/C ,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,cdn,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
总的来说 TCP协议提供可靠的服务, UDP协议提供高效率的服务。
高可靠性的TCP服务提供面向连接的服务,主要用于一次传输大量报文的情形, 如文件传输,远程登录等;
高效率的UDP协议提供无连接的数据报服务,用于一次传输少量的报文。 即使发生传输错误,也可以重新传输并且不会为此付出多少代价。
TCP提供的是面向连接的、可靠的数据流传输,可避免数据传输错误。 面向连接的协议在任何数据传输前就建立好了点到点的连接。
而UDP提供的是非面向连接的、不可靠的数据流传输。当一个UDP数据包在网络中移动时, 发送过程并不知道它是否到达了目的地,除非应用层已经确认了它已到达的事实。 当数据传输的性能必须让位于数据传输的 完整性、 可控制性 可靠性时, TCP协议是当然的选择。 当强调传输性能而不是传输的完整性时, 如:音频和多媒体应用, UDP是最好的选择。 在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下 UDP也是一个好的选择 ,如:DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时, UDP较低的开销使其有更好的机会去传送管理数据。
总结
tcp 提供可靠的服务 若强调 完整性 可靠性可控性 选择tcp
udp 提供高效的服务 若强调 传输性能 选择udp
TCP: 面向连接、传输可靠(保证数据正确性 保证数据顺序)、 用于传输大量数据(流模式)、速度慢,建立连接需要开销较多 (时间,系统资源)。 UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
[1] tcp和udp的区别 简单来说 tcp是有序可靠传输 而udp是不可靠乱序传输 但是实际上你把udp看做IP可能更准确一点 因为可以在udp基础上开发出可靠udp等各种传输.
[2] 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为例子 实际上无论你使用使用紧急指针带外数据 都可以中断数据传输的 这个紧急指针在那里除了保持兼容性 没有实际作用.
[3] 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?
先看下人家怎么选
1 HTTP http协议现在已经深入影响到我们的方方面面,重要性就不说了, 它采用的是tcp 协议,为什么使用tcp 因为它传输的内容是不可以出现丢失,乱序等各种错误的,其次它需要跨平台实现,而tcp满足了这个要求,发展到今天,http享受了tcp带来的简洁高效和跨平台,但是也承受了tcp的各种缺点,例如缺少tcp keep alive机制[这个其实是后来添加的支持,并非普遍实现] tcp协议栈的实现问题引发的难以支持海量用户并发连接[只能通过dns等级别的集群或者cdn来实现],协议太复杂导致很难模块化处理[其实这个问题已经在nginx解决了,nginx通过模块化和对协议的分段处理机制,并引入消息机制,避免了多进程[线程]的频繁切换,相比apache等老牌web服务器软件,在应对大量用户上拥有极大的优势。 即使站在今天的角度看,http也确实应该选择tcp.
2 FTP 这个协议比http更加古老,它采用的也是tcp协议, 因为它的每一个指令,或者文件传输的数据流,都需要保证可靠性,同时要求在各种平台上广泛支持,那么就只能选择tcp 和http不同,它采用了noop指令机制来处理tcp缺少keep alive机制带来的问题,也就是客户端必须每过一段时间,如果没有发送其他指令,就必须发送一个noop指令给服务器,避免被服务器认为是死连接。 Ftp的缺陷在哪里呢? 其次它的文件传输是采用新的数据连接来执行,等于1个用户需要2个连接 其次当一个文件正在传输的时候,你无法进行其他操作,例如列表,也许你可以把它当作是一一对应的典范,因为这样我们可以直接用命令行进行控制,但是很多用户其实是需要在下载的时候同时进行列表等操作的,为了解决这个问题,很多客户端只要开启多个指令连接[和数据连接],这样一来,无形中额外带给了Ftp服务器很多压力,而采用udp可靠传输就不存在这个问题,但是udp可靠传输是没有跨平台支持的,这样是鱼和熊掌不可兼得,对于这样一个简单的开放协议的实现,tcp是个好选择。
3 POP3/SMTP, 常见的邮件协议,没什么好说的,反应--应答模式,跨平台要求,因此tcp是个选择 这个协议的悲剧在于,当初没有考虑到邮件附件会越来越大的问题,因此它的实现中将附件文件采用了base64编码格式,用文本模式进行发送,导致产生了大量的额外流量。
4 TFTP 这是一个非常古老的用于内部传输小文件的协议 没有FTP那么多功能 采用的是udp协议 通过在包中加入包头信息 用尽可能简单的代码来实现小文件传输 注意是小文件 是一个值得参考的udp改造应用范例.
5 通常的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的支持多播,那就很符合这些直播网站了,有时候看直播视频卡顿,人飘逸那可能就是丢包了,但是你也只能往下看。