网络协议之UDP数据包

参照上篇一起阅读更佳:网络协议之TCP/IP协议包

UDP为什么不粘包

为什么TCP有粘包,UDP没有粘包?

TCP是面向流连接,数据的“粘包”问题:客户端发送的多个数据包使用了优化算法(Nagle算法),将多次间隔较小、数据量小的数据包,合并成一个大的数据包发送(把发送端的缓冲区填满一次性发送);接收端底层会把TCP段整理排序交给缓冲区,这样接收端应用程序从缓冲区取数据就只能得到整体数据而不知道怎么拆分。也称数据的无边界性,read()/recv()函数不知道数据包的开始或结束标志(实际上也没有任何开始或结束标志),只把它们当做连续的数据流来处理。

UDP协议是面向数据包协议,不会使用合并优化算法。接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息) ,这样对于接收端来说,就容易进行区分处理了。

所以每次发送UDP数据包都是一条消息,它有明显的边界保护,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据(不像TCP协议在recv/read可以指定大小,读取几次把缓冲区读完或者一次读完几次消息)。这样接收端很容易区分处理,传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。也就是说,发送端send了几次,接收端必须recv几次。接收端一次只能接收发送端发出的一个数据包,如果一次接受数据的大小小于发送端一次发送的数据大小,就会丢失一部分数据,即使丢失,接受端也不会分两次去接收。

// client.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include <unistd.h>

#define LENGTH 24
int main()
{
   
        int sock=socket(AF_INET,SOCK_DGRAM,0);
        if(sock<0)
        {
   
                perror("socket");
                return 2;

        }

        struct sockaddr_in server;
        server.sin_family=AF_INET;
        server.sin_port=htons(
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值