android ROM开发网络下载速度缓慢问题解决方案

由于近期公司项目不断有客户反馈文件下载速度太慢,之前一直以为是客户网络环境原因就没有太在意,直到有反馈说有线网络下载比wifi网络下载要慢很多,网络环境带宽网速等都没问题。详细对比测试后发现的确如此,wifi环境下载能达到10M/s以上,而有线网络下载反而只有3M/s。

最后通过查询资料和多番测试发现是系统tcp缓冲区大小配置问题。可通过proc/sys/net/ipv4/下的各配置文件查看。具体可参考proc/sys/net/ipv4/下各项的意义_技术港湾的技术博客_51CTO博客

我们主要关注/proc/sys/net/ipv4/tcp_rmem和/proc/sys/net/ipv4/tcp_wmem配置文件,决定了tcp收发数据缓冲区大小。以海思3798MV平台为例,并通过curl工具测试下载速度如下:

那么久可以通过修改配置文件来提高tcp缓冲区大小从而提高下载速度,测试如下:

复制代码
echo "524288 1048576 2097152" > /proc/sys/net/ipv4/tcp rmem
echo "262144 524288 10485761" > /proc/sys/net/ipv4/tcp wmem

可以看到下载速度有明显的大幅提升。

关于tcp缓冲区大小默认值配置,可修改内核源码:kernel/linux3.18/net/ipv4/tcp.c中的tcp_init()函数。

复制代码
static void __init tcp_init_mem(void)
{
	unsigned long limit = nr_free_buffer_pages() / 8;
	limit = max(limit, 128UL);
	sysctl_tcp_mem[0] = limit / 4 * 3;
	sysctl_tcp_mem[1] = limit;
	sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
}

void __init tcp_init(void)
{
	struct sk_buff *skb = NULL;
	unsigned long limit;
	int max_rshare, max_wshare, cnt;
	unsigned int i;

	BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));

	percpu_counter_init(&tcp_sockets_allocated, 0, GFP_KERNEL);
	percpu_counter_init(&tcp_orphan_count, 0, GFP_KERNEL);
	tcp_hashinfo.bind_bucket_cachep =
		kmem_cache_create("tcp_bind_bucket",
				  sizeof(struct inet_bind_bucket), 0,
				  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);

	/* Size and allocate the main established and bind bucket
	 * hash tables.
	 *
	 * The methodology is similar to that of the buffer cache.
	 */
	tcp_hashinfo.ehash =
		alloc_large_system_hash("TCP established",
					sizeof(struct inet_ehash_bucket),
					thash_entries,
					17, /* one slot per 128 KB of memory */
					0,
					NULL,
					&tcp_hashinfo.ehash_mask,
					0,
					thash_entries ? 0 : 512 * 1024);
	for (i = 0; i <= tcp_hashinfo.ehash_mask; i++)
		INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].chain, i);

	if (inet_ehash_locks_alloc(&tcp_hashinfo))
		panic("TCP: failed to alloc ehash_locks");
	tcp_hashinfo.bhash =
		alloc_large_system_hash("TCP bind",
					sizeof(struct inet_bind_hashbucket),
					tcp_hashinfo.ehash_mask + 1,
					17, /* one slot per 128 KB of memory */
					0,
					&tcp_hashinfo.bhash_size,
					NULL,
					0,
					64 * 1024);
	tcp_hashinfo.bhash_size = 1U << tcp_hashinfo.bhash_size;
	for (i = 0; i < tcp_hashinfo.bhash_size; i++) {
		spin_lock_init(&tcp_hashinfo.bhash[i].lock);
		INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
	}


	cnt = tcp_hashinfo.ehash_mask + 1;

	tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
	sysctl_tcp_max_orphans = cnt / 2;
	sysctl_max_syn_backlog = max(128, cnt / 256);

	tcp_init_mem();
	/* Set per-socket limits to no more than 1/128 the pressure threshold */
	limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
	max_wshare = min(4UL*1024*1024, limit);
	max_rshare = min(6UL*1024*1024, limit);

    //tcp缓冲区默认值配置
	sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
	sysctl_tcp_wmem[1] = 16*1024;
	sysctl_tcp_wmem[2] = max(64*1024, max_wshare);

	sysctl_tcp_rmem[0] = SK_MEM_QUANTUM;
	sysctl_tcp_rmem[1] = 87380;
	sysctl_tcp_rmem[2] = max(87380, max_rshare);

	pr_info("Hash tables configured (established %u bind %u)\n",
		tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);

	tcp_metrics_init();
	BUG_ON(tcp_register_congestion_control(&tcp_reno) != 0);
	tcp_tasklet_init();
}

注意:如果只是通过shell命令中途修改配置,在网络变化或者设备重启后就会恢复系统默认配置,所以想要永久改变配置还是要通过修改源码实现,或者在应用层每次开机或网络变化时修改一次。

相关推荐
2603_969579281 小时前
内网数据自动备份工具:隔离网络下的数据保护方案
网络
逗脑IDE1 小时前
零基础学ESP32:RFID无线射频卡——让ESP32拥有“刷卡“能力!
开发语言·网络·人工智能·python·esp32·硬件开发
Dovis(誓平步青云)1 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
cws2004011 小时前
监控摄像头选型指南
运维·网络·监控
和裕2 小时前
定制纸箱刀模费全解析:费用定义与可减免合作场景
大数据·运维·网络·人工智能·算法
troy1282 小时前
智能体沙箱:如何为 Agent 模型搭建安全试验场,降低幻觉带来的损失
网络·安全
LHR_friendship2 小时前
HCIP课程全部内容
网络·笔记·学习·hcip·华为ensp
Chengbei112 小时前
拒绝无效洞!蚂蚁Src榜一Clown 2.0 SRC SKill 第二代带状态闭环的白盒 & 黑盒审计 Skill
网络·人工智能·安全·web安全·网络安全·自动化·安全架构
2301_777998343 小时前
TCP协议:滑动窗口与流量控制
服务器·网络·网络协议·tcp/ip·php
156082072193 小时前
使用JFMRFVU3P多通道同步相位测试
网络·人工智能