完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
我在测试视频通话时 发现丢帧特别严重 进行了一些列的排查 发现socket本身似乎有问题
通过测试代码发现了大量的缓冲区溢出 我尝试换了不同的服务器 我还分别测试了wifi网卡和4G网卡 全都这样 无法正常的进行视频通话 不可能才四五百KB/s的速率就不行了啊 好久以前我测试过1M/s都是没问题的 服务器1配置如下 ↓ 服务器2配置如下 ↓ 期待结果和实际结果 软硬件版本信息 01科技K230开发板 + EC200A移远minipcie USB网卡 + RTOS_ONLY 错误日志 通过wifi往腾讯云上传日志如下 ↓ 通过4G网卡移远 EC200A 往雨云上传日志如下 ↓ 尝试解决过程 补充材料 测试代码如下 #include #include #include #include #include #include #include #include #include #include #define TARGET_IP "27.25.142.58"// #define TARGET_IP "162.14.198.185"#define TARGET_PORT 30100#define BUFFER_SIZE 1400#define TARGET_RATE_KB_S 500 // 目标发送速率(KB/s)#define SEND_tiMEOUT_SEC 5 // 发送超时时间(秒)volatile int keep_running = 1;void int_handler(int sig){ keep_running = 0; printf("n接收到中断信号,准备退出...n");}// 创建非阻塞连接int connect_server(){ int sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd < 0) { perror("socket创建失败"); return -1; } // 设置非阻塞 int flags = fcntl(sock_fd, F_GETFL, 0); fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK); // 设置发送超时 struct timeval tv = { SEND_TIMEOUT_SEC, 0 }; setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); // 连接服务器 struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(TARGET_PORT); inet_pton(AF_INET, TARGET_IP, &server_addr.sin_addr); printf("连接 %s:%d...n", TARGET_IP, TARGET_PORT); if (connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { if (errno != EINPROGRESS) { perror("连接失败"); close(sock_fd); return -1; } // 等待连接完成 fd_set wfds; FD_ZERO(&wfds); FD_SET(sock_fd, &wfds); tv.tv_sec = 5; tv.tv_usec = 0; if (select(sock_fd + 1, NULL, &wfds, NULL, &tv) <= 0) { perror("连接超时"); close(sock_fd); return -1; } } printf("已连接n"); return sock_fd;}int main(int argc, char* argv[]){ signal(SIGINT, int_handler); // 初始化缓冲区 unsigned char buffer[BUFFER_SIZE]; memset(buffer, 12, BUFFER_SIZE); // 连接服务器 int sock_fd = connect_server(); if (sock_fd < 0) return -1; printf("开始发送数据 (速率:%d KB/s, 按Ctrl+C停止)n", TARGET_RATE_KB_S); // 计算发送间隔 long delay_us = (long)((double)BUFFER_SIZE / (TARGET_RATE_KB_S * 1024) * 1000000); // 统计变量 unsigned long total_bytes = 0; int packets_sent = 0; int consecutive_errors = 0; struct timeval start_time, current_time, last_success; gettimeofday(&start_time, NULL); last_success = start_time; // 发送循环 while (keep_running) { int bytes_sent = send(sock_fd, buffer, BUFFER_SIZE, 0); if (bytes_sent < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("缓冲区满n"); // 缓冲区满,检查是否需要重连 gettimeofday(¤t_time, NULL); double idle_time = (current_time.tv_sec - last_success.tv_sec) + (current_time.tv_usec - last_success.tv_usec) / 1000000.0; if (idle_time > SEND_TIMEOUT_SEC) { printf("发送超时(%.1f秒),重连...n", idle_time); close(sock_fd); sleep(1); sock_fd = connect_server(); if (sock_fd < 0) break; gettimeofday(&last_success, NULL); consecutive_errors = 0; continue; } usleep(100000); // 等待100ms consecutive_errors++; if (consecutive_errors > 10) { sleep(1); // 连续失败时等待更久 consecutive_errors = 0; } continue; } else { printf("发送错误: %sn", strerror(errno)); break; } } else if (bytes_sent == 0) { printf("连接关闭n"); break; } // 发送成功 consecutive_errors = 0; gettimeofday(&last_success, NULL); total_bytes += bytes_sent; packets_sent++; // 每10个包更新状态 if (packets_sent % 100 == 0) { gettimeofday(¤t_time, NULL); double elapsed = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_usec - start_time.tv_usec) / 1000000.0; printf("已发送: %d包, %luB, 速率: %.2fKB/sn", packets_sent, total_bytes, (total_bytes / 1024.0) / elapsed); } // 控制发送速率 usleep(delay_us); } // 统计结果 gettimeofday(¤t_time, NULL); double total_time = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_usec - start_time.tv_usec) / 1000000.0; printf("n总计: %d包, %luB, 时间: %.2f秒, 平均速率: %.2fKB/sn", packets_sent, total_bytes, total_time, (total_bytes / 1024.0) / total_time); close(sock_fd); return 0;} 以下内容为评论 #include #include #include #include #include #include #include #include #include #include #define TARGET_IP "27.25.142.58"// #define TARGET_IP "162.14.198.185"#define TARGET_PORT 30100#define BUFFER_SIZE 1400#define TARGET_RATE_KB_S 500 // 目标发送速率(KB/s)#define SEND_TIMEOUT_SEC 5 // 发送超时时间(秒)volatile int keep_running = 1;void int_handler(int sig){ keep_running = 0; printf("n接收到中断信号,准备退出...n");}// 创建非阻塞连接int connect_server(){ int sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd < 0) { perror("socket创建失败"); return -1; } // 设置非阻塞 int flags = fcntl(sock_fd, F_GETFL, 0); fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK); // 设置发送超时 struct timeval tv = { SEND_TIMEOUT_SEC, 0 }; setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); // 连接服务器 struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(TARGET_PORT); inet_pton(AF_INET, TARGET_IP, &server_addr.sin_addr); printf("连接 %s:%d...n", TARGET_IP, TARGET_PORT); if (connect(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { if (errno != EINPROGRESS) { perror("连接失败"); close(sock_fd); return -1; } // 等待连接完成 fd_set wfds; FD_ZERO(&wfds); FD_SET(sock_fd, &wfds); tv.tv_sec = 5; tv.tv_usec = 0; if (select(sock_fd + 1, NULL, &wfds, NULL, &tv) <= 0) { perror("连接超时"); close(sock_fd); return -1; } } printf("已连接n"); return sock_fd;}int main(int argc, char* argv[]){ signal(SIGINT, int_handler); // 初始化缓冲区 unsigned char buffer[BUFFER_SIZE]; memset(buffer, 12, BUFFER_SIZE); // 连接服务器 int sock_fd = connect_server(); if (sock_fd < 0) return -1; printf("开始发送数据 (速率:%d KB/s, 按Ctrl+C停止)n", TARGET_RATE_KB_S); // 计算发送间隔 long delay_us = (long)((double)BUFFER_SIZE / (TARGET_RATE_KB_S * 1024) * 1000000); // 统计变量 unsigned long total_bytes = 0; int packets_sent = 0; int consecutive_errors = 0; struct timeval start_time, current_time, last_success; gettimeofday(&start_time, NULL); last_success = start_time; // 发送循环 while (keep_running) { int bytes_sent = send(sock_fd, buffer, BUFFER_SIZE, 0); if (bytes_sent < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("缓冲区满n"); // 缓冲区满,检查是否需要重连 gettimeofday(¤t_time, NULL); double idle_time = (current_time.tv_sec - last_success.tv_sec) + (current_time.tv_usec - last_success.tv_usec) / 1000000.0; if (idle_time > SEND_TIMEOUT_SEC) { printf("发送超时(%.1f秒),重连...n", idle_time); close(sock_fd); sleep(1); sock_fd = connect_server(); if (sock_fd < 0) break; gettimeofday(&last_success, NULL); consecutive_errors = 0; continue; } usleep(100000); // 等待100ms consecutive_errors++; if (consecutive_errors > 10) { sleep(1); // 连续失败时等待更久 consecutive_errors = 0; } continue; } else { printf("发送错误: %sn", strerror(errno)); break; } } else if (bytes_sent == 0) { printf("连接关闭n"); break; } // 发送成功 consecutive_errors = 0; gettimeofday(&last_success, NULL); total_bytes += bytes_sent; packets_sent++; // 每10个包更新状态 if (packets_sent % 100 == 0) { gettimeofday(¤t_time, NULL); double elapsed = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_usec - start_time.tv_usec) / 1000000.0; printf("已发送: %d包, %luB, 速率: %.2fKB/sn", packets_sent, total_bytes, (total_bytes / 1024.0) / elapsed); } // 控制发送速率 usleep(delay_us); } // 统计结果 gettimeofday(¤t_time, NULL); double total_time = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_usec - start_time.tv_usec) / 1000000.0; printf("n总计: %d包, %luB, 时间: %.2f秒, 平均速率: %.2fKB/sn", packets_sent, total_bytes, total_time, (total_bytes / 1024.0) / total_time); close(sock_fd); return 0;} 0 |
|
相关推荐
1个回答
|
|
|
根据你描述的现象(丢帧严重、缓冲区溢出、多种网络环境下重现)和提供的系统信息(K230+RTOS_ONLY+EC200A),问题根源很可能是 嵌入式RTOS环境下的Socket缓冲区配置、数据发送策略与视频流高实时性要求不匹配。以下是详细分析和解决方案: 核心原因分析
针对性解决方案(按优先级推荐)⚙️ 1. 强制减少单个send()的数据包大小 (最可能见效)
⚡ 2. 设置非阻塞模式并使用事件驱动 (核心)
? 3. 探索提升缓冲区大小 (RTOS下常受限)
? 4. 优化发送策略:双缓冲区 + 主动清空
? 5. 升级网络驱动/固件/RTOS (最后手段)
⏱ 6. 考虑网络任务的优先级 (RTOS特性)
? 7. 深入诊断:启用更详细日志
总结执行步骤建议
重点在于应用层强制分包到小于MTU(如1200字节)并且采用非阻塞I/O+事件驱动( |
|
|
|
|
只有小组成员才能发言,加入小组>>
AI_cube训练模型得到了npy文件,没有kmodel文件
773 浏览 0 评论
请问K230 V3.0版本烧录固件和使用IDE到底是烧录哪个啊?
739 浏览 0 评论
443浏览 4评论
AI Cube进行yolov8n模型训练,创建项目目标检测时显示数据集目录下存在除标注和图片外的其他目录如何处理?
463浏览 3评论
autodl算力云在.pt转换onnx文件时正常,但onnx转.kmodel文件时报错,为什么?
554浏览 2评论
如何在大核rtt上把kd_mpi_vicap_start_stream三个摄像头各自出的流拼成一个流呢?
168浏览 2评论
569浏览 2评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-4 00:16 , Processed in 0.935843 second(s), Total 78, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
15771
