在 socket网络程序中,TCP和UDP分别是面向链接和非面向链接的。所以TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的 socket,所以,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将屡次间隔较小且数据量小的数据,合并成一个大的数据块,而后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。
对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是因为UDP支持的是一对多的模式,因此接收端的skbuff(套接字缓冲区)采用了链式结构来记录每个到达的UDP包,在每一个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来讲,就容易进行区分处理了。
保护消息边界和流
那么什么是保护消息边界和流呢?
保护消息边界,就是指传输协议把数据看成一条独立的消息在网上传输,接收端只能接收独立的消息.也就是说存在保护消息边界,接收
端一次只能接收发送端发出的一个数据包.而面向流则是指无保护消息保护边界的,若是发送端连续发送数据,接收端有可能在一次接收动做中,会接收两个或者更多的数据包.
咱们举个例子来讲,例如,咱们连续发送三个数据包,大小分别是2k,4k , 8k,这三个数据包,都已经到达了接收端的网络堆栈中,若是使用UDP协议,无论咱们使用多大的接收缓冲区去接收数据,咱们必须有三次接收动做,才可以把全部的数据包接收完.而使用TCP协议,咱们只要把接收的缓冲区大小设置在14k以上,咱们就可以一次把全部的数据包接收下来.只须要有一次接收动做.
这就是由于UDP协议的保护消息边界使得每个消息都是独立的.而流传输,却把数据看成一串数据流,他不认为数据是一个一个的消息.
因此有不少人在使用tcp协议通信的时候,并不清楚tcp是基于流的传输,当连续发送数据的时候,他们时常会认识tcp会丢包.其实否则,
由于当他们使用的缓冲区足够大时,他们有可能会一次接收到两个甚至更多的数据包,而不少人每每会忽视这一点,只解析检查了第一个
数据包,而已经接收的其余数据包却被忽略了.因此你们若是要做这类的网络编程的时候,必需要注意这一点.
结论:
根据以上所说,能够这样理解,TCP为了保证可靠传输,尽可能减小额外开销(每次发包都要验证),所以采用了流式传输,面向流的传输,
相对于面向消息的传输,能够减小发送包的数量。从而减小了额外开销。可是,对于数据传输频繁的程序来说,使用TCP可能会容易粘包。
固然,对接收端的程序来说,若是机器负荷很重,也会在接收缓冲里粘包。这样,就须要接收端额外拆包,增长了工做量。所以,这个特别适合的是数据要求可靠传输,可是不须要太频繁传输的场合(两次操做间隔100ms,具体是由TCP等待发送间隔决定的,取决于内核中的socket的写法)
而UDP,因为面向的是消息传输,它把全部接收到的消息都挂接到缓冲区的接受队列中,所以,它对于数据的提取分离就更加方便,可是,
它没有粘包机制,所以,当发送数据量较小的时候,就会发生数据包有效载荷较小的状况,也会增长屡次发送的系统发送开销(系统调用,
写硬件等)和接收开销。所以,应该最好设置一个比较合适的数据包的包长,来进行UDP数据的发送。(UDP最大载荷为1472,所以最好能
每次传输接近这个数的数据量,这特别适合于视频,音频等大块数据的发送,同时,经过减小握手来保证流媒体的实时性)算法