龙空技术网

循环打印UDP接收到的h264/g711的RTP包内容

记录生活那些事儿 119

前言:

眼前朋友们对“c语言怎么循环输出”大致比较讲究,看官们都需要剖析一些“c语言怎么循环输出”的相关内容。那么小编同时在网络上搜集了一些关于“c语言怎么循环输出””的相关内容,希望同学们能喜欢,朋友们快快来了解一下吧!

在音视频通信传输中,需要在TCP/UDP的接收处,打印RTP内容的场景很少。我这里是在工作中调试的时候,打印了一次,并用此篇文章做以记录,方便日后使用。

音视频经过H264/G711编码后,都是以十六进制“0x”的方式存储,再通过RTP协议增加RTP头,就可以通过TCP/UDP的协议传输。通常使用抓包工具wiresharek对音视频的网络包进行分析。

<————数据包格式简单了解————>

简单补充下音视频的一点知识,后面有时间慢慢写一些吧。

RTP数据包构成格式:

RTP数据包一般由:Header+载荷(H264裸流、G711裸流等),RTP头12个字节长度。

RTP头结构(真正用到时再看就行)

H264数据包格式:

通常以4字节的0x00000001为固定起始码+NALU单元,其中每一个NALU单元都是有NALU头1字节+真正的码流载荷。并且通过每一个NALU的一字节的NALU头,都可以判断出这个NALU的帧类型。

通过NALU头判断帧类型

<————抓包与接收打印的内容————>

下面图片中,左边是wiresharek抓包分析,右边是打印出的内容:

红色的就是RTP头,12个字节;

黑色的是PS流的头,固定为4个字节0x000001BA;

黄色的是H264裸流的固定起始码,4个字节0x00000001;

绿色的是起始码后的NALU单元的NALU头1个字节,用来判断帧的类型;

<————基于C语言的代码展示————>

以下是基于Linux系统,使用C语言打印recvfrom接收到的H.264码流的RTP包的示例代码:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define BUFFER_SIZE 65536int main() {    int sockfd;    struct sockaddr_in addr;    char buffer[BUFFER_SIZE];    int buffer_size;    // 创建UDP socket    sockfd = socket(AF_INET, SOCK_DGRAM, 0);    if (sockfd < 0) {        fprintf(stderr, "Failed to create socket\n");        return 1;    }    // 绑定本地地址和端口    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl(INADDR_ANY);    addr.sin_port = htons(1234);    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {        fprintf(stderr, "Failed to bind socket\n");        close(sockfd);        return 1;    }    // 循环接收RTP包并打印    while (1) {        struct sockaddr_in remote_addr;        socklen_t remote_addr_len = sizeof(remote_addr);        buffer_size = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&remote_addr, &remote_addr_len);        if (buffer_size < 0) {            fprintf(stderr, "Failed to receive data\n");            close(sockfd);            return 1;        }        printf("Received RTP packet from %s:%d, size=%d\n", inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port), buffer_size);        // 打印RTP包的内容        for (int i = 0; i < buffer_size; i++) {            printf("%02x ", (unsigned char)buffer[i]);            if (i % 16 == 15) {                printf("\n");            }        }        printf("\n");    }    // 关闭socket    close(sockfd);    return 0;}

【多余的解释:】

上述代码创建了一个UDP socket,并绑定到本地地址和端口。然后循环接收RTP包并打印,直到程序被中断。接收到的RTP包的内容会以十六进制形式打印出来。可以根据需要修改代码,将RTP包的内容解析成NAL单元并进行处理。

标签: #c语言怎么循环输出 #c语言密码锁程序循环代码