UDP协议(用户数据报协议):是一种面向无连接、不可靠、面向数据报的传输层通信协议。 主要特性:
- 面向无连接:UDP不需要和TCP一样需要在通信前通过握手建立连接,可以随时发送数据。在发送端,应用层将数据传递给传输层的UDP协议,UDP只会给数据增加一个UDP头标识,表示是UDP协议然后就传递给网络层。
- 有单播,多播,广播的功能;
- 面向报文;
- 不可靠性:不需要建立连接,想发就发,收到什么数据就传递什么数据,并且不会备份数据,也不关心对方是否已经正确接收。
TCP协议(传输控制协议):是一种面向连接的、可靠的、基于字节流的传输层通信协议。 主要特性:
1.面向连接: 应用程序在使用TCP之前必须先建立TCP传输连接,同理传输完毕后必须释放已建立的TCP连接。 2.仅支持单播传输: 每条TCP连接只能有两个端点,只能进行点对点的数据传输,不支持多播或广播。 3.基于字节流的: TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。“流”指的是流入到进程或从进程流出的字节序列。 4.可靠性: TCP传输是可靠的,可靠性的保证主要依靠七种机制:校验和、序列号、确认应答机制、超时重传机制、连接管理机制、流量控制、拥塞控制。
基于TCP实现的协议
HTTP,SSH,FTP,Telnet,SMTP
TCP/UDP协议常见面试题
问题1:解释三次握手和四次挥手? 答:三次握手: 首先由客户端向服务器端发送一个SYN包请求连接,客户端进入SYN-SEND状态,服务端收到客户端发来的SYN包后,将建立连接的SYN包和一个ACK应答包发送回客户端,服务器端进入SYN—RECV状态。此时客户端接收到服务端发来的SYN+ACK包后,再返回一个ACK应答包给服务器,服务器接收后建立连接成功。 四次挥手: 客户端首先发送FIN包给服务端,告诉服务端数据发完了,随后客户端进入FIN-WAIT-1状态,服务器端接收到后会进入CLOSE-WAIT状态,并回给客户端一个应答包ACK,并将剩余DATA发送完毕,客户端接收到ACK应答后会进入到FIN-WAIT-2状态。服务端剩余数据发送完毕后再向客户端发送一个FIN包,表示服务端的数据也发完了,随后进入LAST-ACK状态。客户端接收到FIN包后再向服务器发送一个应答ACK包,并进入到TIME-WAIT状态,服务器进入CLOSE状态。 问题2:为什么不能两次握手?
答: 假设客户端先发送一个SYN包给服务器,却因为网络原因迟迟发送不到位,此时因为客户端没有收到服务器的ACK包而第二次发送SYN包,这一次发送被成功接收,并且服务器回应ACK给客户端,连接建立成功。但经过一段时间后,第一次发送的SYN包终于到达服务器端,此时服务器端认为这是客户端的一次新建连接,于是同意连接并发送ACK给客户端,而客户端此时不会理会这个ACK,导致服务器端就会一直等待客户端发送数据,造成资源浪费。而在三次握手中,第三次握手可以确保连接的成功,如果服务器端等不到第三次握手则会认为SYN是无效的并且释放资源。
问题3:TCP和UDP的区别? 答:
1.TCP面向连接而UDP是无连接的;
2.TCP提供可靠的服务,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,不保证可靠性;
3.TCP是基于字节流传输的,而UDP是面向报文的;
4.TCP连接只能是点对点,一对一;而UDP支持一对一,一对多,多对一以及多对多的交互通信;
5.TCP首部开销20字节;UDP的首部开销小,只有8字节。
问题4:tcp三次握手失败了,两端如何处理? 答: 服务端回复ack+syn后,如果超时得不到ack回复,则会发送rst重置连接报文,然后释放套接字。 问题5:TIME_WAIT有什么用? 答: TIME_WAIT是主动关闭连接的一方进行最后一次ack回复后进入的状态。 作用:处理可能因为最后一次ACK丢失而导致对方重传的fin包。如果主动关闭方回复最后一次ack后直接释放资源,就有可能在新的客户端中使用原来的这个地址信息,而如果上次ack丢失的情况下重传fin,则新客户端收到重传的fin对新连接造成影响,以及发送syn也会收到影响。 TIME_WAIT更多的是为了保护客户端启动不会使用刚关闭的套接字地址信息,而受到上个套接字的通信遗留问题影响。 问题6:TIME_WAIT为什么是2MSL? 答: 是为了保证能够对超时重传的fin进行处理,以及保证本次通信的所有数据都消失在网络中,不会对新连接造成影响。 如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存在在网络里的老TCP报文可能与新TCP连接报文冲突,造成数据冲突。为避免此冲突,需等待上次连接中的报文全部消除,2MSL时间可以满足这个需求。 问题7:一台主机上出现了大量的TIME_WAIT是什么原因?如何解决? 答: 由于TIME_WAIT是主动关闭连接方所进入的状态,因此出现这种情况意味着大量的主动关闭套接字情况存在。 解决方法: 1.减少TIME_WAIT等待时间 2.使用套接字选项:地址复用 Int setsockopt(int fd,int level,int optname, void*optval, int optlen); 问题8:一台主机上出现了大量的CLOSE_WAIT是什么原因?如何解决? 答: CLOSE_WAIT是被动关闭方收到FIN包并进行回复后进入的状态,出现这种情况意味着是某种情况下对方关闭了socket链接,但是我方忙与读或者写,没有关闭连接。代码需要判断socket,一旦读到0,断开连接,read返回负,检查一下errno,如果不是AGAIN,就断开连接。
|