TCP、UDP协议

1.TCP、UDP的区别

1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2.TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

3.UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

4..每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5.TCP对系统资源要求较多,UDP对系统资源要求较少。

 

2.TCP相比UDP有哪些优势

UDP以其简单、传输快的优势,在越来越多场景下取代了TCP,如实时游戏。

(1)网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。

(2)TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程,由于TCP内置的系统协议栈中,极难对其进行改进。

采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大,基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成影响。

3、UDP和TCP编程步骤也有些不同,如下:

TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;

TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;

UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;

UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;

4.TCP三次握手,四次挥手

   tcp首部

                        

1.源端口号:表示发送端端口号,字段长为16位。
2.目标端口号:表示接收端口号,字段长为16位。
3.序列号:表示发送数据的位置,字段长为32位。每发送一次数据,就累加一次该数据字节数的大小。
注意:序列号不会从0或1开始,而是在建立连接时由计算机生成的一个随机数作为其初始值,通过SYN包发送给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。
4.确认序号:表示下一次应该收到的数据的序列号,字段长为32字节。发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。
5.首部长度:该字段长度为4位,单位为4字节(32位)。TCP首部长度不包括选项的话,是20个字节,20/4=5,5的二进制序列:0101,报头长度也叫数据偏移,所以该字段可以设置为5,选项字段最大的是40字节,所以,TCP首部长度为最大为20+40=60字节,该字段可以设置的最大长度为60/4=15。
6.保留:该字段主要是为了以后扩展时使用,其长度为4位。一般设置为0,即使收到的包在该字段不为0,此包也不会丢弃。
控制位:字段长为6,每一位从左到右分别为:URG、ACK、PSH、RST、SYN、FIN。当对应的值为1,表示有具体含义。
字段|含义
URG|紧急指针是否有效。为1,表示某一位需要被优先处理。
ACK|确认号是否有效,一般置为1。
PSH|提示接收端应用程序立即从TCP缓冲区把数据读走。
RST|对方要求重新建立连接,复位。
SYN|请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1.
FIN|希望断开连接。
7.窗口大小:接收缓冲区的大小,TCP不允许发送超过此处所示大小的数据。
8.校验和:发送端填充,CRC校验,接收校验不通过,则认为数据有问题。和UDP的区别是,UDP校验的是数据本身,TCP校验的不仅包含TCP首部,而且包含TCP数据部分。
9.紧急指针:只有在URG为1时有效,该字段为1表示本报文的段中的紧急数据的指针。
10.选项:用于提高TCP的传输性能。需要根据首部长度进行控制,其最大长度为40字节。

我们在着重讲一下在三次握手和四次挥手中的用到序列号、确认号及标志位。
1. 序列号seq

占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生,给字节编上序号后,就给每一个报文段指派一个序号,序列号seq就是这个报文段中的第一个字节的数据编号。
2. 确认号ack

占4个字节,期待收到对方下一个报文段的第一个数据字节的序号,序列号表示报文段携带数据的第一个字节的编号,而确认号指的是期望接受到下一个字节的编号,因此挡墙报文段最后一个字节的编号+1即是确认号。
##3. 确认ACK
占1个比特位,仅当ACK=1,确认号字段才有效。ACK=0,确认号无效。
4. 同步SYN

连接建立时用于同步序号。当SYN=1,ACK=0表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使用SYN=1,ACK=1.因此,SYN=1表示这是一个连接请求,或连接接收报文,SYN这个标志位只有在TCP建立连接才会被置为1,握手完成后SYN标志位被置为0.
5. 终止FIN

TCP三次握手以及四次挥手的过程

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(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(最后确认)状态,等待客户端的确认。
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

常见面试题

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

【问题3】为什么不能用两次握手进行连接?

答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

       现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

5.那些协议是基于TCP,那些是基于UDP的?
 

基于TCP的应用层协议有:SMTP、TELNET、HTTP、FTP

基于UDP的应用层协议:DNS、TFTP(简单文件传输协议)、RIP(路由选择协议)、DHCP、BOOTP(是DHCP的前身)、IGMP(Internet组管理协议)

6.TCP连接

短连接

连接->传输数据->关闭连接

HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束后就中断连接。短连接是指SOCKET连接后发送后接收完数据后马上断开连接。

长连接

连接->传输数据->保持连接->传输数据->....->关闭连接

长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。

那什么场景下使用长连接或者短连接?

长连接多用于操作频繁,点对点的通讯(及时通讯),而且连接数不能太多。每个TCP连接都需要三次握手,建立连接,会比较耗时。如果每个操作都要先连接,再操作的话,处理速度会降低很多。长连接的特点是每个操作完后都不断开连接,直接发送数据包就可以了,不需要每次都建立连接。

使用场景如下:

1.数据库的连接用长连接。如果用短连接频繁的通信会造成socket错误,而且频繁的socket创建也是对资源的浪费。

2.像web网站的http服务一般都是用短连接,因为长连接对于服务器来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一点资源,如果用长连接,而且同时又成千上万的用户,如果每个用户都占用一个连接的话,并发量大,对服务器的压力比较大。如果每个用户无需频繁操作情况下需用短连接。

在长连接中一般无法判断读写什么时候结束,必须要加长度报文头。读函数先是读取报文头的长度,再根据这个长度读相应长度的报文。

7.TCP是如何实现可靠传输的

TCP可靠传输方面,主要采用以下4种机制:

  1. 字节编号机制。TCP 数据段以字节为单位对数据段中的“数据”部分进行一一编号,确保每个字节的数据都可以有序传送和接受。
  2. 数据段确认机制。TCP 要求每接受一个数据段都必须由接收端向发送端返回一个确认数据段(可以用一个去人数据段一次确认全面多个数据段),其中的“确认号”表明接收端已正确接受的数据段序号(“确认号”前面的所有数据段,确认号表示将要接收的下一个数据段编号)。
  3. 超时重传机制。在 TCP 中有一个重传定时器(Retransmission Timer, RTT),在发送一个数据段的同时也启动了该定时器。如果在定时器过期之前该数据段还没有被对方确认的话,且定时器停止,然后重传对应序号的数据段。
  4. 选择性确认(Selective ACK, SACK)机制。在 SACK 支持下,仅可以重传缺少部分的数据,而不会重传那些已经正确接受的数据段。

 

 

 

 

                              

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值