【Network】UDP 大包怎么发? MTU怎么设置?

本文介绍如何在发送视频数据时处理超过MTU的UDP大包,通过分包发送并添加标识进行重组。在接收端,由于UDP的不可靠性,采取缓冲区管理和顺序校验来确保数据正确重组。示例代码展示了分包和重组的过程,使用libevent的evbuffer进行数据处理。此外,文章建议在处理int类型数据时考虑字节序转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      这里主要用UDP来发送视频,当发送的数据大于1500时分包发送,保证每包小于1500.
发送好办,分割后循环发就可以了,关键是接收时的处理。
先做一下处理的方法 :
发送时每包上面加上标识,比如RTP的做法是加时间戳,SSRC,媒体类型还有结束标识。简单参考一下,我们也加上一些标识(直接拿RTP头也可以, 不过我们的目标是更简洁一些)。另外,我们的目的和RTP稍有不同,UDP库当时设计是传输数据,而不关心数据的内容是什么。这样,简单一化,包头第一个INT定义为类型,第二个INT为序号,第三个为结束标志,之后是数据长度和数据内容。
代码演示:

int CUDPSession::SplitData(char* pBuff, uint32_t nLen)
{
int nBlockNum = nLen / UDP_BLOCK_SIZE;
if (nLen % UDP_BLOCK_SIZE != 0)
{
nBlockNum++;
}


int sendlen = 0;
for (int i = 0; i < nBlockNum; i++)
{
int poayload_size = UDP_BLOCK_SIZE;
char* payload = pBuff + UDP_BLOCK_SIZE * (i);


if (nLen - UDP_BLOCK_SIZE * (i) < UDP_BLOCK_SIZE)
poayload_size = nLen - UDP_BLOCK_SIZE * (i);


CPackOut* pack = new CPackOut;
(*pack) << PACK_TYPE_DATA;
(*pack) << m_nFrameIndex;
if (i == nBlockNum - 1)
{
(*pack) << 1;
}
else
{
(*pack) << 0;
}
(*pack) << poayload_size;
(*pack).SetBuffer(payload, poayload_size);

int ret = SendPacket(pack, m_destIP, m_destPort);
printf("SendPacket ret = %d\n", ret);
sendlen += ret;
delete pack;
pack = NULL;
}

return sendlen;
}

<think>我们被要求回答“UDP通信是否需要建立连接”这个问题。根据提供的引用,我们可以直接找到答案。引用[1]明确指出:“UDP-不需要建立连接的通信协议。”并且解释:“UDP没有 TCP的接收确认、窗口等机制,因此在收数据之前也不需要交换控制信息,也就是说不需要建立和断开连接的步骤”。引用[2]也提到:“UDP协议是无连接协议,因此传输的数据不需要建立连接就可以直接送”。因此,我们可以明确回答:UDP通信不需要建立连接。同时,我们可以根据引用内容简要解释UDP的特点,比如无连接、开销小、适合实时性要求高的场景等。另外,引用[4]中提到了connect()函数,但注意这个函数在UDP中也可以使用,但它的作用与TCP不同。在UDP中使用connect()并不会真正建立连接,而只是将套接字与一个特定的对端地址关联,这样可以避免每次送数据时指定地址,也可以过滤接收的数据(只接收来自该地址的数据)。但是,这并不改变UDP无连接的本质。因此,在回答中我们需要强调UDP本身是无连接的,即使使用了connect()函数也不会建立类似TCP那样的连接。回答结构:1.直接回答问题:UDP通信不需要建立连接。2.解释UDP无连接的含义。3.对比TCP的连接建立过程(三次握手)和UDP的直接送。4.提及UDP中使用connect()函数的作用(可选,以澄清可能的误解)。5.总结UDP适用于哪些场景(根据引用[2])。同时,根据系统指令,我们需要在回答末尾生成相关问题。注意:引用标识要自然地添加在引用内容的末尾。</think>### UDP通信是否需要建立连接? **不需要建立连接。** UDP协议是一种**无连接协议**,通信双方在传输数据前**无需建立连接**,也无需断开连接的步骤。这是UDP与TCP最核心的区别之一[^1][^2]。 #### 关键特性说明: 1. **无连接机制** - 送方直接构造数据包(添加UDP头部)后交给IP层送,无需握手过程[^1] - 接收方被动监听端口,收到即处理,无连接状态维护 *示例代码:UDP数据包直接送* ```c // 伪代码:UDP直接送数据(无连接步骤) udp_sendto(pcb, data_packet, &target_ip, target_port); ``` 2. **协议开销对比** | 特性 | UDP | TCP | |--------------|--------------------------------------|--------------------------------------| | 连接建立 | ❌ 无需建立 | ✅ 需三次握手 | | 可靠性保证 | ❌ 不保证数据到达和顺序 | ✅ 通过确认重传机制保证 | | 头部开销 | 8字节 | 20字节以上 | | 适用场景 | 实时传输、小数据包、可容忍丢包[^2] | 文件传输、需可靠连接的场景[^2] | 3. **技术原理** - UDP数据包最大长度理论为$65,507$字节(IP包最大长度$65,535$字节 - IP头$20$字节 - UDP头$8$字节)[^3] - 实际传输受MTU限制(以太网默认$1500$字节),超长数据会被IP层分片 4. **特殊函数说明** 虽然UDP有`connect()`函数(引用[4]),但其作用仅为: - 绑定默认目标地址(避免每次指定) - **不进行实际连接握手**,不改变无连接本质[^4] #### 典型应用场景 - **传感器数据上报**:温度/湿度等周期性小数据包 - **实时音视频传输**:如视频会议(容忍个别帧丢失) - **DNS查询**:单个请求/响应包即可完成[^1] - **组播/广播**:如网络时间协议(NTP)同步[^2] > **总结**:UDP通过牺牲可靠性换取低延迟,其“即即忘”的特性使其成为物联网设备、实时系统的理想选择,但开者需自行处理丢包和乱序问题[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值