TCP通信与UDP通信

UDP服务器

输层主要应用的协议模型有两种,一种是TCP协议,另外一种则是UDP协议。TCP协议在网络通信中占主导地位,绝大多数的网络通信借助TCP协议完成数据传输。但UDP也是网络通信中不可或缺的重要通信手段。

相较于TCP而言,UDP通信的形式更像是发短信。不需要在数据传输之前建立、维护连接。只专心获取数据就好。省去了三次握手的过程,通信速度可以大大提高,但与之伴随的通信的稳定性和正确率便得不到保证。因此,我们称UDP为“无连接的不可靠报文传递”。

TCP通信和UDP通信各自的优缺点:

TCP:面向连接的可靠的、基于字节流的传输层通信协议。其传输的单位是报文段。对于不稳定的网络层,采取完全弥补的通信方式。丢包重传

特征:面向连接、 只能点对点(一对一)通信、 可靠交互、 全双工通信、 面向字节流

优点,稳定。 数据流量稳定、速度稳定、顺序

缺点:传输速度慢。效率低。开销大。

使用场景:数据的完整型要求较高,不追求效率。
大数据传输、文件传输。

UDP:无连接的,提供面向事务的简单不可靠信息传送服务,其传输的单位是用户数据报。对于不稳定的网络层,采取完全不弥补的通信方式。默认还原网络状况

特征:无连接、 尽最大努力交付、 面向报文、 没有拥塞控制、 支持一对一、一对多、多对一、多对多的交互通信、 首部开销小(只需8字节,TCP需要20字节)

优点:传输速度快。效率高。开销小。

缺点:不稳定。 数据流量。速度。顺序。

使用场景:对时效性要求较高场合。稳定性其次。
游戏、视频会议、视频电话。腾讯、华为、阿里—应用层数据校验协议,弥补up的不足。

与TCP类似的,UDP也有可能出现缓冲区被填满后,再接收数据时丢包的现象。由于它没有TCP滑动窗口的机制,通常采用如下两种方法解决:

  1. 服务器应用层设计流量控制,控制发送数据速度。

  2. 借助setsockopt函数改变接收缓冲区大小。如:

    #include <sys/socket.h>
    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
    int n = 220x1024
    setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));

C/S模型-TCP

基于TCP协议的客户端/服务器程序的一般流程:
在这里插入图片描述
服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回。

TCP 为什么要进行三次握手?

【答案一】:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
【答案二】:因为双方都需要确认对方收到了自己发送的序列号,确认过程最少要进行三次通信。
【答案三】:因为信道不可靠,而 TCP 想在不可靠信道上建立可靠地传输,那么三次通信是理论上的最小值。(而 UDP 则不需建立可靠传输,因此 UDP 不需要三次握手。)

TCP 为什么要进行四次挥手?

【问题一】:TCP 为什么要进行四次挥手? / 为什么 TCP 建立连接需要三次,而释放连接则需要四次?

【答案一】:因为 TCP 是全双工模式,客户端请求关闭连接后,客户端向服务端的连接关闭(一二次挥手),服务端继续传输之前没传完的数据给客户端(数据传输),服务端向客户端的连接关闭(三四次挥手)。所以 TCP 释放连接时服务器的 ACK 和 FIN 是分开发送的(中间隔着数据传输),而 TCP 建立连接时服务器的 ACK 和 SYN 是一起发送的(第二次握手),所以 TCP 建立连接需要三次,而释放连接则需要四次。

【问题二】为什么 TCP 连接时可以 ACK 和 SYN 一起发送,而释放时则 ACK 和 FIN 分开发送呢?(ACK 和 FIN 分开是指第二次和第三次挥手)

【答案二】因为客户端请求释放时,服务器可能还有数据需要传输给客户端,因此服务端要先响应客户端 FIN 请求(服务端发送 ACK),然后数据传输,传输完成后,服务端再提出 FIN 请求(服务端发送 FIN);而连接时则没有中间的数据传输,因此连接时可以 ACK 和 SYN 一起发送。

【问题三】为什么客户端释放最后需要 TIME-WAIT 等待 2MSL 呢?

【答案三】为了保证客户端发送的最后一个 ACK 报文能够到达服务端。若未成功到达,则服务端超时重传 FIN+ACK 报文段,客户端再重传 ACK,并重新计时。
防止已失效的连接请求报文段出现在本连接中。TIME-WAIT 持续 2MSL 可使本连接持续的时间内所产生的所有报文段都从网络中消失,这样可使下次连接中不会出现旧的连接报文段。

TCP 黏包问题

【原因】:TCP 是一个基于字节流的传输服务(UDP 基于报文的),“流” 意味着 TCP 所传输的数据是没有边界的。所以可能会出现两个数据包黏在一起的情况。

【解决】:1.发送定长包。如果每个消息的大小都是一样的,那么在接收对等方只要累计接收数据,直到数据等于一个定长的数值就将它作为一个消息。
2.包头加上包体长度。包头是定长的 4 个字节,说明了包体的长度。接收对等方先接收包头长度,依据包头长度来接收包体。
3.在数据包之间设置边界,如添加特殊符号 \r\n 标记。FTP 协议正是这么做的。但问题在于如果数据正文中也含有 \r\n,则会误判为消息的边界。

TCP 如何保证可靠传输:

确认和超时重传、 数据合理分片和排序、 流量控制、 拥塞控制、 数据校验

流量控制:

如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。流量控制策略就是控制发送者的发送速度,使得接收者来得及接收,达到不丢失分组的目的。流量控制是构成TCP可靠性的一方面。
流量控制目的是防止分组丢失

主要使用滑动窗口机制(连续ARQ协议)实现,滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制

流量控制引发的死锁
当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。

持续计时器
为了避免流量控制引发的死锁,TCP 使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

拥塞控制:

拥塞控制:防止过多的数据注入到网络,导致网络中的路由器或链路过载。
拥塞控制的算法:慢开始、拥塞避免、快重传、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值