为何Keil HTTP服务器向iPhone传包速度、频率均高于同网络PC?
问题场景复现
- 运行环境:开发板部署Keil官方HTTP Web Server,前端页面通过JavaScript实现周期逻辑,每50ms调用
fetch接口拉取dynamic.cgx动态文件 - 单PC接入网络:文件可稳定按50ms间隔返回,
fetch请求平均耗时1~2ms,无明显延迟 - 多设备接入网络:网络中加入其他联网设备后,PC侧数据传输速率骤降,
fetch请求响应等待时长超过500ms - 对照组测试结果:同多设备场景下iPhone无严重延迟问题,仅出现轻微速率下降,表现远优于PC;该差异与浏览器类型无关,iPhone端Chrome、Safari测试结果一致
- 现有排查素材:已采集单PC接入、PC+其他设备接入两个场景下PC侧的Wireshark抓包数据,暂未获取移动设备侧抓包
差异根因分析
核心矛盾是Keil配套的RL-TCPnet协议栈、HTTP Web Server是面向极低资源MCU设计的轻量实现,TCP收发缓冲区、并发连接处理能力极弱,PC和iOS端默认TCP协议栈、网络请求行为的差异,直接导致了服务端压力的天壤之别:
- 并发连接数策略差异
桌面端Chrome、Edge等浏览器对同一HTTP域名默认开放68个并发TCP连接,50ms周期的无排队`fetch`很容易在短时间内占满所有并发连接,瞬间打满开发板上通常只有12KB大小的TCP收发缓冲区,后续数据包直接被服务端丢弃。而iOS系统对同域名并发连接数限制为3~4个,系统网络层还会自动对高频短请求做节流,不会瞬间冲爆服务端缓冲区。 - TCP拥塞控制、重传策略差异
桌面端Windows/macOS/Linux系统默认TCP初始拥塞窗口更大,检测到丢包(也就是服务端缓冲区溢出丢的包)时会立刻进入拥塞避免状态,主动降低发送速率,且桌面端TCP重传超时(RTO)初始值默认设为200ms以上,超时后按指数退避,很容易堆出500ms以上的等待延迟。iOS的TCP栈专门针对弱网、小带宽场景做了优化,初始拥塞窗口更小,RTO初始值设置更低,遇到少量丢包会优先触发快速重传,不会进入长时间的超时等待,因此延迟上涨幅度极小。 - 请求排队逻辑差异
桌面浏览器不会主动拦截高频无等待的fetch请求,当前一个请求还没返回时,新的请求会直接占用新的并发连接发出去,进一步加剧服务端缓冲区压力;iOS系统网络框架会自动对同目标的高频请求做串行排队处理,请求发送节奏更平缓,不会给服务端造成突发流量压力。
快速验证&修复方案
- 调整前端请求逻辑:去掉固定50ms定时触发的逻辑,改成上一个
fetch请求收到响应后,再延时50ms发起下一次请求,从根源避免请求堆积 - 调整开发板协议栈参数:将RL-TCPnet中HTTP服务对应的TCP收发缓冲区大小调至4KB以上,关闭TCP延迟确认(Delayed ACK)选项
- 强制短连接:给
fetch请求添加Connection: close请求头,避免长连接上的请求排队 - 对照验证:手动修改PC网卡的TCP参数,将初始拥塞窗口、并发连接数下调到和iOS接近的水平,即可观察到PC侧延迟表现和iPhone基本一致
内容的提问来源于stack exchange,提问作者Daniel Schuck
相关产品推荐
相关产品推荐

