本文原创为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参数的更多相关文章

  1. Linux内核源代码解析——TCP状态转移图以及其实现

    本文原创为freas_1990,转载请标明出处http://blog.csdn.net/freas_1990/article/details/10223581 TCP状态转移的原理并不高深,但是处理逻 ...

  2. Linux内核源代码解析之——我与神童聊Linux内核

    本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/11619609 我的朋友里,至少有2.5个神童. 有的 ...

  3. Linux内核源代码解析——用户发送数据包的起源之sendto

    本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/10162853 Jack:我想知道用户如何把数据发送到 ...

  4. Linux内核源代码解析之TCP面向字节流

    本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/11264237 大家都知道TCP是面向stream,而 ...

  5. Linux内核源代码情景分析系列

    http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统  5.1 概述 构成一个操作系统最重要的就 ...

  6. Linux内核源代码获取教程

    Linux内核源代码获取方法 什么叫Linux 什么叫Linux内核 Linux内核源代码的获取 什么叫Linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UN ...

  7. 在windows下解压缩Linux内核源代码出现重复文件原因

    在windows下解压缩Linux内核源代码出现重复文件原因 2009年06月30日 13:35 来源:ChinaUnix博客 作者:embededgood 编辑:周荣茂     原因一.因为在Lin ...

  8. Linux内核源代码

    说明:只供学习交流 一,目录结构 Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具有可读性. 二,目录结构 arch目录 arch是archite ...

  9. Linux内核源代码目录树结构

    Linux内核源代码目录树结构. arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录.和32位PC相关的代码存放在i386目录下,其中比较重要的包括kernel(内核核心部分).mm(内 ...

随机推荐

  1. 谈谈Facebook的聊天系统架构

    今天看到一份 Facebook 公司 2009 年的 Slideshow, 介绍它的聊天系统架构, 其中的一张图结构非常清晰, 所以我对这张图谈谈我的看法. Web Tier: 用 PHP 开发, 聊 ...

  2. BZOJ 1622: [Usaco2008 Open]Word Power 名字的能量

    题目 1622: [Usaco2008 Open]Word Power 名字的能量 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 349  Solved ...

  3. java学习之字符流与字节流的转换

    package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExce ...

  4. Drainage Ditches(最大流)

    Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64044   Accepted: 2471 ...

  5. JavaScript 高级程序设计(第3版)笔记——chapter4:变量、作用域和内存问题

    Chapter4 变量.作用域和内存问题 l  理解基本类型和引用类型的值 l  理解执行环境 l  理解垃圾收集 4.1基本类型和引用类型的值 l  ECMAScript变量包含两种不同数据类型的值 ...

  6. C++,常成员函数

    #include <iostream> using namespace std; class Test { public: int x; int y; void const_m1() co ...

  7. MFC工程的复制

    MFC工程的复制 [1]       在VS中新建一个同类型的MFC工程. [2]       复制.rc资源文件,用记事本打开旧工程和新工程的.rc文件,将旧工程的对应部分复制到新工程的对应部分,文 ...

  8. Reapter 添加删除按钮

    repeater中的删除按钮和datagrid下的删除在实现上,还是有一定的区别的,由于repeater在客户端生成的html代码是非常干净的,所以特别受到众多web2.0网站的欢迎(不像datagr ...

  9. USACO Palindromic Squares 【STL__string_的应用】

    这里有个讲解 string 用法非常详细的博文:https://www.byvoid.com/zhs/blog/cpp-string 题目意思很简单啦,就是找回文 使用string可以高速A过 Sou ...

  10. Codeforces 486B - OR in Matrix

    矩阵的 OR ,也是醉了. 题目意思很简单,就是问你有没有这么一个矩阵,可以变化,得到输入的矩阵. 要求是这个矩阵每行都可以上下任意移动,每列都可以左右任意移动. 解题方法: 1.也是导致我WA 的原 ...