首页 > 技术文章 > linux-TCP和UDP的差异项

chenfengyijiu 2021-03-15 23:29 原文

udp为什么是不可靠的?bind和connect对于udp的作用是什么?

 

1、UDP使用connect 的好处?

1、能够捕获错误。因为UDP是无状态的,使用connect会在内核中建立一个类似额的TCP的维护,这样当网络异常时进行ICMP回应时内核会通知应用,如果不使用connect 的话就接收不到错误

2、UDP多次调用connect,会断开之前的连接,建立新的连接。但是TCP只能使用一次

3、提高效率,

普通发送:建立连接->发送报文->断开连接->建立连接->发送报文->断开连接

connect:建立连接->发送报文->发送报文

4、高并发增加稳定性,避免服务端相同的端口收到了其他的对端的数据

5、使用sendto和recvfrom需要指定端口和IP,但是使用connect就是需要使用一次

2、UDP使用bind 的意义:

1、服务器知道客户端的端口的话,客户端就可以bind,进行监听数据

2、如果服务器想先发送数据的话,客户端就需要进行bind,否则服务器必须要等到客户端建立连接发送数据之后才知道对端的端口和IP

3、使用bind可以指定端口发送

3、TCP和UDP与MTU的关系

TCP是属于数据流,但是UDP是数据包。TCP中的每次应用发送都是按照流一样的效果,TCP有组包协议,每次发送和接收都会有对应的分包和组包,TCP保证了应用接收的顺序,TCP发送的包大于MTU的时候会进行拆包,每个包都有TCP协议头,进行校验和重发。

但是UDP是数据包服务。每次UDP调用都发进行发送,UDP在内核中没有发送缓冲区,也不会进行数据复制,每次发送都会立即发送,当UDP发送到包大于MTU的时候。IP会进行拆包处理,首次UDP的会带有UDP头,但是后面的包没有带有头,网络的包容易丢失之后,IP进行组包的时候就会校验不过,导致整个数据包丢失。UDP的包最好要小于MTU,降低丢包风险。

4、TCP和UDP发送

当发送端应用程序使用sendto(或write)函数向一个TCP连接写入数据时,内核中的TCP模块首先把这些数据复制到与该连接对应的TCP内核发送缓冲区中,然后TCP模块调用IP模块提供的服务,传递的参数包括TCP头部信息和TCP发送缓冲区中的数据,即TCP报文段。

经过UDP封装后的数据称为UDP数据报 。UDP对应用程序的封装与TCP类似。不同的是,UDP无须为应用层数据保存副本,因为它提供的服务是不可靠的。当一个UDP数据报被成功发送之后,UDP内核缓冲区中的该数据报就被丢弃了(因此UDP没有真正意义上的发送缓冲区,sendto的数据直接交给内核,由内核进行交给网络层)。如果应用程序检测到该数据报未能被接受端正确接收,并打算重新发送这个数据报,则应用程序需要重新从用户空间将该数据拷贝到UDP内核中。

总结:TCP有内核缓冲区,保证TCP的可靠到达,需要进行分组和重传,但是UDP没有,UDP没有内核缓冲区,数据

数据都是直接发送到底层,进行通讯.UDP需要应用进行校验是否可靠到达,UDP数据包没有发送成功需要应用进行重新发送.

5、TCP和UDP

TCP是字节流;应用程序对数据的发送和接收是没有边界限制。

UDP是数据流,应用每次调用一次send,UDP模块就会将数据发送出去。

4、黏包问题

TCP通讯是字节流,应用层拿到数据之后没有明显的边界,就产生了黏包问题。解决方案:1、包是定长 2、可变包,带有长度 3、固定分隔符

UDP包是数据流,只有收到和未收到,不存在边界问题

推荐阅读