【发布时间】:2013-03-29 16:09:00
【问题描述】:
我在 C 程序中向 250 个节点发送 icmp echo。 套接字是这样创建的
sfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
我有getsockopt SO_RCVBUF :262142 .i.e 262KB 由于一个数据包需要84字节(包括IP,100字节在线),所以rcv缓冲区应该能够容纳 262142/84 = 3120 个数据包
sysctl parameters (defaults)
net.core.rmem_max = 131071
net.core.rmem_default = 113664
但有 10 多滴。
我正在发送所有回显请求,然后使用 recvfrom() 获取数据包。 很明显,回复数据包在套接字的 rcv 缓冲区中累积, 但是 rcv 缓冲区足够大,可以容纳 3120 个数据包。
数据包在接收主机上正确显示。
当我设置时:
sysctl -w net.core.rmem_max=1048576
and SO_RCVBUF to 2MB, the drops were 0.
为什么会这样?
活动中的队列很少。
- 网卡环形缓冲区。
- nic 到内核队列
- 每个套接字 rcv 缓冲区
我猜 net.core.rmem_max 只会改变每个套接字 rcv 缓冲区。
任何指向正确方向的链接。
Platform Linux suse10/x86
网卡:英特尔公司 PRO/无线 2200BG
--添加更多
我禁用了上述无线接口并开始使用有线接口 以太网控制器:Broadcom Corporation NetXtreme BCM5705M_2 千兆以太网(rev 03) 情况发生了重大变化。
net.core.netdev_budget = 300
net.core.netdev_max_backlog = 1000
net.core.rmem_max = 131071
net.core.wmem_max = 131071
getsockopt SO_RCVBUF :262142
getsockopt SO_SNDBUF :262142
# ethtool -g eth1
Current hardware settings:
RX: 200
TX: 200
#
eth1 txqueuelen:1000
现在每 250 个数据包 0 丢包,每 1000 个包大约 170 个丢包 使用 ethtool -G 将 rx,tx 从默认值 200 更改为无效。
然后我更改了每个套接字 rcv 缓冲区的最大值
sysctl -w net.core.rmem_max=1024000
这允许每 6000 次掉落 0 次 每 7000 滴 500 滴
进一步增加 per-socket-rcv-buffer-max
sysctl -w net.core.rmem_max=2048000
每 7000 个数据包 0 丢包
有线网络给出了更加一致和合作的结果。
但问题仍然悬而未决 当 262142 字节缓冲区可以容纳 3000 个大小为 84 的数据包(带有 IP 标头)时,为什么会在 1000 个数据包时发生丢包。 即使在线数据包最大为 100 字节,262142 也可以容纳 2600 个数据包。
ethereal 大部分时间都能够获取数据包,并且 ifconfig 计数器显示没有丢包,因此这是 nic 驱动程序将数据包提供给内核之后发生的事情。
ethereal 也丢失了一些数据包,但这种情况较少发生。
只改变上面的这些
sysctl -w net.core.rmem_max=1024000
下降 96/1000 掉落 0/6000
下降 500/7000
sysctl -w net.core.rmem_max=2048000
下降 0/7000
sysctl -w net.core.rmem_max=512000
sysctl -w net.core.netdev_max_backlog=3000
下降 0/3000
sysctl -w net.core.rmem_max=256000
sysctl -w net.core.netdev_max_backlog=3000
下降 1400/3000
hold = 2 * 1024 * 1024;
setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold));
for(;;)
...
if(recvfrom(sfd,(char *)packet, packlen, 0, (struct sockaddr *)&from, &fromlen)) < 0) {
rcvcount++;
process_packet(packet,packlen);
}
【问题讨论】:
标签: linux networking