前言:
眼前朋友们对“c语言怎么循环输出”大致比较讲究,看官们都需要剖析一些“c语言怎么循环输出”的相关内容。那么小编同时在网络上搜集了一些关于“c语言怎么循环输出””的相关内容,希望同学们能喜欢,朋友们快快来了解一下吧!在音视频通信传输中,需要在TCP/UDP的接收处,打印RTP内容的场景很少。我这里是在工作中调试的时候,打印了一次,并用此篇文章做以记录,方便日后使用。
音视频经过H264/G711编码后,都是以十六进制“0x”的方式存储,再通过RTP协议增加RTP头,就可以通过TCP/UDP的协议传输。通常使用抓包工具wiresharek对音视频的网络包进行分析。
<————数据包格式简单了解————>
简单补充下音视频的一点知识,后面有时间慢慢写一些吧。
RTP数据包构成格式:
RTP数据包一般由:Header+载荷(H264裸流、G711裸流等),RTP头12个字节长度。
H264数据包格式:
通常以4字节的0x00000001为固定起始码+NALU单元,其中每一个NALU单元都是有NALU头1字节+真正的码流载荷。并且通过每一个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语言密码锁程序循环代码