- 浏览: 1407123 次
- 性别:
- 来自: 火星
-
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
文章列表
我们这次主要来分析相关的两个断开函数close和shotdown以及相关的套接口选项SO_LINGER。这里要注意SO_LINGER对shutdown无任何影响。它只对close起作用。
先来坎SO_LINGER所对应的数据结构:
struct linger {
///linger的开关
int l_onoff; /* Linger active */
///所等待的时间。
int l_linger; /* How long to linger for */
};
这里对这个套接口选项就不详细介绍了,在unix网络编程中有详细的介绍,我们这里只会分析内核的处理代码。
...
这里只是一个摘要。具体的细节还需要去看manual。
1 info 用来描述你的程序的状态,比如info b就是显示出当前的程序的所有断点.
2 set 用来设置一些环境变量的值,比如set prompt $.
3 show用来描述gdb自己的状态.
编译要用-g选项.
然后用gdb +程序名,或者直接gdb后,用file + 文件名加载程序.
1 run/r 运行程序.
2 set args 设置程序的参数.
3 path directory 加一个目录到环境变量path
4 set directory 设置gdb的工作目录
5 pwd 当前的工作目录
6 att ...
这次我们来看后面的3个定时器;
首先是keep alive定时器。
这个定时器主要是由于一条连接可能长时间idle,此时就需要发送探测包,来探测对端是否存活,如果对端收到这个探测包,它会立即相应一个ack,而当接受到ack之后,我们就能确认对端是存活的。否则我们会认为这个连接除了问题。
这个定时器是当一个新的连接变为establish状态的时候被激活,如果在当定时器超时还没有数据到来,定时器回调函数就会被激活,从而发送探测包。
在linux中,keep alive定时器不仅实现了keep alive而且还实现了syn ack定时器。并且这个定时器必须主动被打开,我们在用户空间通过设置SO ...
- 2009-10-05 20:52
- 浏览 5457
- 评论(0)
在内核中tcp协议栈有6种类型的定时器:
1 重传定时器。
2 delayed ack定时器
3 零窗口探测定时器
上面三种定时器都是作为tcp状态机的一部分来实现的。
4 keep-alive 定时器
主要是管理established状态的连接。
5 time_wait定时器
主要 ...
相比于发送数据,接收数据更复杂一些。接收数据这里和3层的接口是tcp_v4_rcv(我前面的blog有介绍3层和4层的接口的实现).而4层和用户空间,也就是系统调用是socket_recvmsg(其他的读取函数也都会调用这个函数).而这个系统调用会调用__sock_recvmsg.下面我们就先来看下这个函数。
它的主要功能是初始化sock_iocb,以便与将来数据从内核空间拷贝到用户空间。然后调用
recvmsg这个虚函数(tcp协议的话也就是tcp_recvmsg).
static inline int __sock_recvmsg(struct kiocb *iocb, struct ...
- 2009-09-26 20:24
- 浏览 14568
- 评论(0)
nginx采用的也是大部分http服务器的做法,就是master,worker模型,一个master进程管理站个或者多个worker进程,基本的事件处理都是放在woker中,master负责一些全局初始化,以及对worker的管理。
在nginx中master和worker的通信是通过socketpair来实现的,每次fork完一个子进程之后,将这个子进程的socketpaire句柄传递给前面已经存在的子进程,这样子进程之间也就可以通信了。
nginx中fork子进程是在ngx_spawn_process中进行的:
第一个参数是全局的配置,第二个参数是子进程需要执行的函数,第三个参数是p ...
在分析之前先来看下SO_RCVTIMEO和SO_SNDTIMEO套接口吧,前面分析代码时没太注意这两个.这里算是个补充.
SO_RCVTIMEO和SO_SNDTIMEO套接口选项可以给套接口的读和写,来设置超时时间,在unix网络编程中,说是他们只能用于读和写,而像accept和connect都不能用他们来设置.可是我在阅读内核源码的过程中看到,在linux中,accept和connect可以分别用SO_RCVTIMEO和SO_SNDTIMEO套接口来设置超时,这里他们的超时时间也就是sock的sk_rcvtimeo和sk_sndtimeo域.accept和connect的相关代码我前面都介绍 ...
- 2009-09-10 01:41
- 浏览 19843
- 评论(1)
阿宝同学推荐了这个东西,因此周末就大概看了下源码,这里就简要的分析下它的实现,下面是他的特性。
项目地址在这里:
http://code.google.com/p/ydb/
引用# YDB is a key-value storage library.
# Simple API, only 6 methods (open, close, sync, get, set ...
- 2009-09-06 18:02
- 浏览 2023
- 评论(0)
先来看下accept的实现.
其实accept的作用很简单,就是从accept队列中取出三次握手完成的socket,并将它关联到vfs上(其实操作和调用sys_socket时新建一个socket类似).然后返回.这里还有个要注意的,如果这个传递给accept的socket是非阻塞的话,就算accept队列为空,也会直接返回,而是阻塞的话就会休眠掉,等待accept队列有数据后唤醒他.
接下来我们就来看它的实现,accept对应的系统调用是 sys_accept,而他则会调用do_accept,因此我们直接来看do_accept:
long do_accept(int fd, str ...
- 2009-09-03 00:34
- 浏览 5230
- 评论(0)
首先来看下内核如何处理3次握手的半连接队列和accept队列(其实也就是server端的三次握手的状态变换).而半连接队列和accept队列在内核如何表示,我们上次已经介绍过了,这里就不介绍了.
首先我们知道当3层的数据包到达之后会调用4层的协议handle,tcp的话就是tcp_v4_rcv.如何调用可以看我前面的blog:
而在tcp_v4_rcv中,则最终会调用tcp_v4_do_rcv来处理输入数据包.在看tcp_v4_do_rcv之前,我们先来看在tcp_v4_rcv中,内核如何通过4元组(目的,源端口和地址)来查找对应得sock对象.
在分析之前,我们要知道,当一对tcp连接 ...
- 2009-09-01 00:46
- 浏览 8450
- 评论(0)
bind的实现:
先来介绍几个地址结构.
struct sockaddr 其实相当于一个基类的地址结构,其他的结构都能够直接转到sockaddr.举个例子比如当sa_family为PF_INET时,sa_data就包含了端口号和ip地址(in_addr结构).
struct sockaddr {
sa_family_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
接下来就是sockaddr_in ,它表示了所有的ipv4 ...
- 2009-08-23 04:10
- 浏览 5854
- 评论(0)
首先来看整个与socket相关的操作提供了一个统一的接口sys_socketcall.
下面就是它的代码片段:
asmlinkage long sys_socketcall(int call, unsigned long __user *args)
{
unsigned long a[6];
unsigned long a0, a1;
int err;
..........................................
a0 = a[0];
a1 = a[1];
switch (call) {
case SYS_SOCKET:
...
- 2009-08-15 04:38
- 浏览 21132
- 评论(4)
首先来看一下基于3层的ipv4以及ipv6实现的一些4层的协议:
这里要注意并没有IGMPV6,这是因为在ipv6中,它是作为iCMPv6的一部分实现的.
首先我们要知道输入数据包的ip头中的protocol域标识了,将要传递的4层协议.
我们这里主要介绍的是ip数据包从3层传递到4层的接口(也就是输入帧接口).而输出帧的处理,我前面的blog都已经有介绍,想了解的话,可以去看前面的blog.
先来看主要的数据结构,然后我们会分析ip_local_deliver_finish函数(也就是3层处理的出口函数).
在内核中,每一个4层协议都是一个net_protocol结构体, ...
- 2009-08-08 03:50
- 浏览 6225
- 评论(0)
glibc中的strlen的实现主要的思想就是每次检测4个字节(long int)。这样的话就降低了循环的次数,从而从整体上提高了效率。
这里它使用了两个技巧,一个是由于传进来的字符串的地址有可能不是4字节(long int)对其的,因此首先需要遍历字符串从而找到4字节对其的那个地址。然后再进行比较.
第二个技巧就是如何高效的判断4个字节中是否有字节为0.
下来来看源码,这个源码的注释还是满详细的。这里主要都是一些位计算的技巧:
size_t
strlen (str)
const char *str;
{
const char *char_ptr;
const ...
这次主要介绍一些ip层管理以及统计相关的东西.
首先来看 long-living ip peer information.
我们知道ip协议是无状态的协议.这里内核为了提升性能.为每个目的ip地址(换句话说,也就是和本机进行通信过的主机)保存了一些信息.
peer子系统一般是被tcp,或者routing子系统所使用.
这个信息的数据结构是inet_peer,它是一棵avl树,每个节点的key就是一个ip地址.由于是avl树,因此每次搜索都是O(lg n):
struct inet_peer
{
///avl树的左子树和右子树
struct inet_peer *avl_lef ...
- 2009-08-01 21:40
- 浏览 3739
- 评论(0)