在做一个项目,通过UDP接收TS流并转码。做的过程中发现,假如输入的TS流码率很大(10Mb/s),丢包现象很严重,根本不能正常解码。我在程序中明明已经通过设置SO_RCVBUF把接收缓冲设置成1MB了,但为什么丢包还怎么严重呢?
通过搜索,找到了问题所在。测试代码如下
void Socket::SetRecvBufSize(int v_size)
{
int rcv_bufsize = v_size;
socklen_t optlen;
printf("before %d\n", rcv_bufsize);
::setsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (char*)&rcv_bufsize, sizeof(int));
optlen = sizeof(int);
::getsockopt(m_fd, SOL_SOCKET, SO_RCVBUF, (char*)&rcv_bufsize, &optlen);
printf("after %d\n", rcv_bufsize);
}
运行结果
before 1048576
after 262142
说明setsockopt没有起作用。通过man 7 socket,可以看到这样一段话
SO_RCVBUF
Sets or gets the maximum socket receive buffer in bytes. The
kernel doubles this value (to allow space for bookkeeping over-
head) when it is set using setsockopt(2), and this doubled value
is returned by getsockopt(2). The default value is set by the
rmem_default sysctl and the maximum allowed value is set by the
rmem_max sysctl. The minimum (doubled) value for this option is
256.
所以要用更大的接收缓冲,必须修改系统内核参数
vi /etc/sysctl.conf,添加一行
net.core.rmem_max = 4194304
sysctl -p,使参数生效。再次启动程序,可以看到缓冲也跟着增大了
before 1048576
after 2097152
丢包现象立马几乎绝迹。
(yeyingxian) |