项目涉及基于UDP的socket通讯,该部分的基本状况以下:html
其余说明:web
本地收发。若是不限制发包速率将会很是快vim
基于UDP。使用recvfrom()函数收包缓存
recvfrom()接收后当即将包加入队列并封装处理,即一次处理单个包socket
发包流量最大160Mbps = 20MBpstcp
多种流量:160Mbps,80Mbps,40Mbps等进行测试svg
可是如今测试出现的问题以下:函数
收包率低/丢包率高。测试
最大容量下耗时超过了发包耗时大数据
收包率低/丢包率高的缘由分析
(1) 缓存过小,不能及时接收数据。
(2)recvfrom()接收到数据以后处理速度太慢
(1) 缓存过小不能及时接收数据
[1] 分析:
UDP无需真正的发送缓冲区:
UDP是没有流量控制的:
所以,若是socket接收缓存设置太小,就会由于UDP包过大或者发包速率过快而丢包
[2] 解决方法:从新设置UDP接收缓冲区大小
UDP接收缓冲区最小值:sysctl -a | grep rmem
UDP发送缓冲区默认值:cat /proc/sys/net/core/wmem_default
[3] 解决步骤:
调整UDP缓冲区大小:使用函数setsockopt()函数修改接收缓冲区大小
或
从新设置系统缓冲区最大值,再调整UDP缓冲区大小:
打开配置文件:sudo vim /etc/sysctl.conf
在文件末尾添加:net.core.rmem_max = 6291456
执行配置:sysctl -p
从新查看最大值:cat /proc/sys/net/core/rmem_max
发现系统接收缓冲最大值已改变,此时能够经过setsockopt函数设置更大接收缓存。发送缓冲最大值也能够经过相似方式修改:net.core.wmem_max = 6291456,sysctl -p
/* setsockopt()函数修改:*/
//函数原型
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
sockfd: 标识一个套接字的描述字
level: 选项定义的层次:支持SOL_SOCKET, IPPROTO_TCP, IPPROTO_IP,和IPPROTO_IPV6
optname:需设置得选项 SO_RCVBUF(接收缓冲区),SO_SNDBUF(发送缓冲区)
optval:指针,指向存放选项待设置的新值的缓冲区
optlen:optval的大小
//示例
int recv_size = 2 * 1024 * 1024; //设置为4M
setsockopt(s,SOL_SOCKET, SO_RCVBUF, (const char *)&recv_size,sizeof(recv_size));
(2)recvfrom()接收到数据以后处理速度太慢
[1] 分析:
UDP无需真正的缓冲区,没必要保存应用进程的数据拷贝
recvfrom()接收速率并非系统受限因素
数据处理是速度受限因素之一
线程挂起再唤醒耗时受限速度之二
[2] 解决方法:
[3] 解决步骤:
TCP接收缓冲区大小
TCP接收缓冲区大小
注:经过cat /proc/sys/net/ipv4/tcp_wmem命令和cat /proc/sys/net/core/wmem_max命令得出的TCP发送缓冲区最大值不一致,我以为应该以cat /proc/sys/net/ipv4/tcp_wmem为准,即最大值为4M。
2017.07.29 文中错误和不足部分,欢迎交流指正