TCP、UDP区别及使用场景
从TCP和UDP的特点来看,连接性,可靠性,以及面向字节流还是数据报来说。
区别:
连接性:TCP面向连接,而UDP无连接。对TCP来说,在数据传输之前,通信双发需要建立一条稳定的通信连接,也就是我们说的三次握手;对UDP来说,数据直接发送。
可靠性:TCP提供可靠的数据传输服务,他确保如果数据没有按照顺序到达或丢包,TCP会自动重传;对UDP来说,他不提供可靠的数据传输服务,数据没有按照顺序到达或者丢包,并不会重传,但这并不意味着是缺点,因为这样就决定了他的传输速度较快,因为没有TCP的确认和重传机制,所以我们可以理解为这是他们的特点。
数据报:TCP是面向字节流的协议,将数据划分为较小的数据包进行传输,并且会根据网络情况进行调整,也就是说网络情况会影响接收端窗口和拥塞窗口大小,也就影响了滑动窗口大小,也就会影响在更短时间内发送更多的数据。
流量控制与拥塞控制:TCP拥有流量控制和拥塞控制机制,能够根据网络状况自送调整数据包的发送效率,避免网络拥塞;而UDP没有这些控制机制,如果网络拥塞,可能会导致数据包丢失或延迟。
TCP使用场景:
- 文件传输:如FTP文件传输协议,因为TCP保证了数据的完整性,适合传输大量数据。
- 网页浏览:HTTP/HTTPS,用于获取网页内容时,也依赖于TCP的可靠性。
- 远程登录:SSH和telnet,这些需要稳定的连接来维护会话状态。
- 数据库管理系统:TCP确保了数据库的一致性和完整性,防止数据丢失和损坏。
UDP使用场景:
- 实时音视频传输:如在线直播,视频会议等,UDP的低延迟和高效性使其成为首选。
- 在线游戏:UDP的快速传输和低延迟可以实现实时的游戏数据传输。
- DNS查询:域名系统通常使用UDP进行快速的查询响应。
- 实时传感器数据:UDP适用于需要快速传输实时传感器数据的场景,例如工业自动化,物联网等。
TCP三次握手和四次挥手的过程
- 第一次握手:客户端向服务端发送一个设置了SYN标志位的管理报文,表示请求建立连接。客户端进入SYN_SEND状态,等待服务器确认。
- 第二次握手:服务器收到客户端发来的SYN管理报文,向客户端发送一个设置了SYN+ACK标志位的管理报文作为应答,服务器进入SYN_RECV状态,准备接收客户端的确认。
- 第三次握手:客户端收到来自服务端的SYN+ACK管理报文,向服务器发送一个ACK管理报文,表示确认收到了服务器的响应,客户端和服务端都进入ESTABLISHED状态,表示连接建立成功,双方可以开始数据传输。
- 第一次挥手:客户端向服务器发送一个设置了FIN标志位的管理报文,表示不再发送数据,客户端进入FIN_WAIT_1状态,等待服务器的确认。
- 第二次挥手:服务器收到客户端的FIN管理报文,向客户端发送一个ACK管理报文,服务器进入CLOSE_WAIT状态,等待自己的应用程序关闭连接,此时,服务器还可以继续向客户端发送数据,客户端收到服务器的ACK应答,进入FIN_WAIT_2状态。
- 第三次挥手:当服务器也完成数据发送后,他向客户端发送一个设置了FIN标志位的管理报文,表示字节的数据也发送完毕,请求关闭连接,服务器进入LAST_ACK状态,等待客户端的确认。
- 第四次挥手:客户端收到服务器的FIN管理报文后,向服务器发送一个ACK应答,客户端进入TIME_WAIT状态,等待一段时间,通常是2MSL,即报文最大存活时长,以确保服务器收到了自己的ACK应答,服务器收到这个应答后,关闭连接,进入CLOSED状态,客户端在等待时间结束后也关闭连接,进入CLOSED状态。
socket常见函数和操作
对于TCP来说:
socket创建套接字,第一个参数是设置本地通信还是网络通信,我们要进行网络通信就设置成AF_INET,第二个参数决定了是TCP通信还是UDP通信,对TCP来说,我们就设置成:SOCK_STREAM,我们从名字上也看的出来是TCP,因为TCP是面向字节流的,第三个参数指定使用的协议,通常,某个协议中只有一种特定的类型,我们设置为0,表示使用默认的协议。
用于服务器程序,允许服务器重启时立即绑定到之前的地址和端口,而不需要等待之前的连接超时。
绑定套接字到指定的IP地址和端口号上,这样,来自该IP地址和端口号的数据包就可以正确的路由到该套接字上。
listen设置套接字为监听状态,表示可以接受来自客户端的请求。
当客户端想要与服务器发送通信时,会调用connect来申请连接,accept是用来获取连接的:
对于UDP来说,就不需要listen,connect,accept,setsockopt这些函数了,因为他是无连接的。
我们还需要介绍一些发送和接受消息的函数:
recvfrom和recv,sendto和send,对于recvfrom和sendto来说,适用于未连接的套接字,而recv和send适用于已连接的套接字,也就是说,recvfrom和sendto适用于TCP,而recv和send适用于UDP。
get请求和post请求区别
- 应用场景:get请求主要用于请求数据,而post请求主要用于提交数据到服务器。
- 安全性与参数传递:get请求参数一般拼接在URL后面,直接暴露在地址栏上,因此安全性较低;而post请求参数一般放在请求体重,不会在地址栏上显示,所以相对于get请求来说安全性更高。
- 缓存与记录:get请求主要用于请求数据且参数暴露在URL中,所以他可以被浏览器缓存。post请求主要用于提交数据,且参数不暴露在URL中,所以他通常不会被浏览器缓存。
- 请求长度限制:由于get请求拼接在URL后面,而URL的长度在浏览器和服务器中都有一定的限制,所以在get请求中发送的数据量有限。而post请求将参数放在请求体重,因此理论上没有请求长度的限制,这使得post请求可以发送大量数据,适用于文件上传等场景。
- 编码方式:get请求只能进行URL编码,这意味着他只能发送ASCII字符集的数据,如果需要发送非ASCII字符,如中文,就需要进行URL编码。post请求支持多种编码方式,这使得post请求可以发送更加复杂和多样化的数据。
- TCP数据包:get请求在发送请求时,浏览器会将HTTP头部和数据一起发送初秋,服务器响应200,这通常意味着get请求只产生一个TCP数据包。post请求发送时,浏览器首先发送Http头部,服务器响应100,然后浏览器再发送数据部分,服务器再次响应200,这通常意味着post请求会产生两个TCP数据包(Firefox除外,他只发送一次)。
如何解决分包、粘包问题
解决分包问题
分包问题通常是指在数据传输过程中,一个完整的数据包被分割成多个较小的部分进行传输,在某些情况下,如网络限制和MTU限制等,数据包可能会被哦底层网络协议分割,以下是一些解决策略:
- 调整MTU大小,是网络接口层能够传输的最大数据包大小。
- 应用层分包,在应用层对数据包进行分割,确保每个数据包的大小都适合网络传输,这种方法需要发送方和接受方都遵循相同的分包规则。
解决粘包问题
粘包问题是指多个数据包被合并成一个数据包进行传输。TCP协议的基于字节流的特性使得粘包问题尤为常见。
- 自定义协议,报文长度+报文内容+固定分隔符
- 增加接受缓冲区大小:接收方可以增加接受缓冲区的大小,一遍能够存储更多的数据。这可以减少因为缓冲区不足而导致的粘包问题,但也会增加内存消耗和延迟。
- 循环读取判断数据包是否完整。