Linux内核源代码解析之——sock's buffer参数
本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/11539695
关于socket与sock的关系再简单说一下。
socket是面向文件与API的,拿来给application程序员fuck。
而sock是面向数据包的,用来发送用户的数据和接收网卡传到内核的数据。
我们再看一下sock的结构体定义。
struct sock {
...
volatile unsigned long wmem_alloc;
volatile unsigned long rmem_alloc;
...
unsigned short rcvbuf;
unsigned short sndbuf;
...
};
注意,这里的rcvbuf和sendbuf不是缓冲区,而只是一个可调整的参数。通过setsocketopt()可以这两个参数进行调整。
其中的wmem_alloc和rmem_alloc是动态变化的,实时记录了当前sock获取了多少rcvbuf。
那为什么需要设置wmem_alloc这样的一个值呢?
在计算机的内存管理里,有这样的一个技术——用一个值来记录当前(server)使用了多少内存,所有的内存分配,释放会记录到这个变量里,以做到对内存的实时反馈。
在Linux内核里,在redis里也有,相信在很多别的server代码里也会有。
如果不使用这样的变量会出现什么样的问题呢?
这个问题我暂时不给出答案,大家可以思考一下。
那什么时候这几个变量会起作用呢?
我们来看一下下面的代码。
struct sk_buff *
sock_wmalloc(struct sock *sk, unsigned long size, int force,
int priority)
{
if (sk) {
if (sk->wmem_alloc + size < sk->sndbuf || force) {
struct sk_buff * c = alloc_skb(size, priority);
if (c) {
cli();
sk->wmem_alloc+= size;
sti();
}
return c;
}
DPRINTF((DBG_INET, "sock_wmalloc(%X,%d,%d,%d) returning NULL\n",
sk, size, force, priority));
return(NULL);
}
return(alloc_skb(size, priority));
}
当我们发送一个数据包的时候,会调用sock_wmalloc函数,这个函数会把当前sock已经分配的内存(wmem_alloc)和马上会分配的数据包内存相加后与sndbuf比较,如果大于sndbuf的话,就不能发送这个包。
从这里,可以看出来,sndbuf其实只是一个参数,它是可以动态调整,也是可以忽视的(如果force参数被设置了)。
那这两个参数是何时被初始化的呢?
来看一下如下代码
static int
inet_create(struct socket *sock, int protocol)
{
struct sock *sk;
struct proto *prot;
int err; sk = (struct sock *) kmalloc(sizeof(*sk), GFP_KERNEL);
...
sk->sndbuf = SK_WMEM_MAX;
sk->rcvbuf = SK_RMEM_MAX;
...
if (sk->prot->init) {
err = sk->prot->init(sk);
if (err != 0) {
destroy_sock(sk);
return(err);
}
}
return(0);
}
我们再来看一下,setsocketopt是如何修改这个参数的。
/* * This is meant for all protocols to use and covers goings on * at the socket level. Everything here is generic. */
int sock_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen) { int val; int err; ... case SO_SNDBUF: if(val>32767) val=32767; if(val<256) val=256; sk->sndbuf=val; return 0; ... case SO_RCVBUF: if(val>32767) val=32767; if(val<256) val=256; sk->rcvbuf=val; return(0); ... default: return(-ENOPROTOOPT); } }
那sock里的skb数据结构是如何控制的呢?
那一张漂亮的图是如何画出来的呢?
Linux内核源代码解析之——sock's buffer参数的更多相关文章
- Linux内核源代码解析——TCP状态转移图以及其实现
本文原创为freas_1990,转载请标明出处http://blog.csdn.net/freas_1990/article/details/10223581 TCP状态转移的原理并不高深,但是处理逻 ...
- Linux内核源代码解析之——我与神童聊Linux内核
本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/11619609 我的朋友里,至少有2.5个神童. 有的 ...
- Linux内核源代码解析——用户发送数据包的起源之sendto
本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/10162853 Jack:我想知道用户如何把数据发送到 ...
- Linux内核源代码解析之TCP面向字节流
本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/11264237 大家都知道TCP是面向stream,而 ...
- Linux内核源代码情景分析系列
http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统 5.1 概述 构成一个操作系统最重要的就 ...
- Linux内核源代码获取教程
Linux内核源代码获取方法 什么叫Linux 什么叫Linux内核 Linux内核源代码的获取 什么叫Linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UN ...
- 在windows下解压缩Linux内核源代码出现重复文件原因
在windows下解压缩Linux内核源代码出现重复文件原因 2009年06月30日 13:35 来源:ChinaUnix博客 作者:embededgood 编辑:周荣茂 原因一.因为在Lin ...
- Linux内核源代码
说明:只供学习交流 一,目录结构 Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具有可读性. 二,目录结构 arch目录 arch是archite ...
- Linux内核源代码目录树结构
Linux内核源代码目录树结构. arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录.和32位PC相关的代码存放在i386目录下,其中比较重要的包括kernel(内核核心部分).mm(内 ...
随机推荐
- qt qml 利用xmlhttprequest 调用有赞api
最近朋友在有赞商城上面开了一个店铺,因为有实体店,一般卖商品后送货上门,但是打票时候老是人工用world文档人工复制黏贴订单打印小票, 所以就找我帮忙做一个软件专门打印小票的,就研究起来调用有赞第三方 ...
- Android 6.0 新特性 整理 资料来自网络
Android 6.0新特性 Runtime Permissions Doze and App Standby Apache HTTP Client Removal BoringSSL Access ...
- unix ls命令
[语法]: ls [-RadCxmlnogrtucpFbqisf1] [文件夹或文件......] [说明]: ls 命令列出指定文件夹下的文件,缺省文件夹为当前文件夹 ./,缺省输出顺序为纵向 ...
- if语句求三个数中最大的
Console.WriteLine("请输入第一个数:"); int a = Convert.ToInt32( Console.ReadLine()); Console.Write ...
- 界面控件 - 滚动条ScrollBar(对滚动条消息和鼠标消息结合讲的不错)
界面是人机交互的门户,对产品至关重要.在界面开发中只有想不到没有做不到的,有好的想法,当然要尝试着做出来.对滚动条的扩展,现在有很多类是的例子. VS2015的代码编辑是非常强大的,其中有一个功能可以 ...
- 互联网创业十问?good(快速迭代、把握核心用户应对抄袭,不需要把商业模式考虑完备,4种失败的信号,失败者没资格说趁着年轻...)
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:曹政链接:https://www.zhihu.com/question/20264499/answer/28168079来源: ...
- C#操作Excel(读/写)
http://www.cnblogs.com/litianfei/archive/2008/03/21/1116906.html 写的很详细 一.操作Excel 首先导出Excel (1)示例: // ...
- 下载并在Eclipse中关联Android源代码
大家都知道文档写的好当然让人非常舒服,可是有时候文档再好也不如直接看源代码来的直接,既然Android是开源的,为什么不在eclipse里直接看它的源代码呢? 1.下载源代码 这部分网上有大量的资料, ...
- 二路单调自增子序列模型【acdream 1216】
题目:acdream 1216 Beautiful People 题意:每一个人有两个值,能力值和潜力值,然后要求一个人的这两个值都严格大于第二个人的时候,这两个人才干呆在一块儿,给出很多人的值,求最 ...
- MySQL新建用户,授权,删除用户,修改密码等命令
首先要声明一下:一般情况下,修改MySQL密码,授权,是需要有mysql里的root权限的. 注:本操作是在WIN命令提示符下,phpMyAdmin同样适用. 用户:phplamp 用户数 ...