struct sock详解
以下内容来自<br />http://hi.baidu.com/linux%5Fkernel关于unix网络编程的一个不错的blog,作者应该是搞协议栈,对于写应用程序的人来说,看这些东西有利于分析问题;推荐看看. struct sock详解<br />2006年08月11日 星期五 下午 02:17 结构体sock是套接口在网络层的表示,在代码include/net/sock.h 174行
·
关于unix网络编程的一个不错的blog,作者应该是搞协议栈,对于写应用程序的人来说,看这些东西有利于分析问题;推荐看看.
struct sock详解
2006年08月11日 星期五 下午 02:17
2006年08月11日 星期五 下午 02:17
结构体sock是套接口在网络层的表示,在代码include/net/sock.h 174行定义,下面是其内容:
struct sock {
struct sock_common __sk_common;
#define sk_family __sk_common.skc_family
#define sk_state __sk_common.skc_state
#define sk_reuse __sk_common.skc_reuse
#define sk_bound_dev_if __sk_common.skc_bound_dev_if
#define sk_node __sk_common.skc_node
#define sk_bind_node __sk_common.skc_bind_node
#define sk_refcnt __sk_common.skc_refcnt
unsigned char sk_shutdown : 2,
sk_no_check : 2,
sk_userlocks : 4;
unsigned char sk_protocol;
unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
struct xfrm_policy *sk_policy[2];
rwlock_t sk_dst_lock;
atomic_t sk_rmem_alloc;
atomic_t sk_wmem_alloc;
atomic_t sk_omem_alloc;
struct sk_buff_head sk_receive_queue;
struct sk_buff_head sk_write_queue;
int sk_wmem_queued;
int sk_forward_alloc;
unsigned int sk_allocation;
int sk_sndbuf;
int sk_route_caps;
int sk_hashent;
unsigned long sk_flags;
unsigned long sk_lingertime;
struct sock {
struct sock_common __sk_common;
#define sk_family __sk_common.skc_family
#define sk_state __sk_common.skc_state
#define sk_reuse __sk_common.skc_reuse
#define sk_bound_dev_if __sk_common.skc_bound_dev_if
#define sk_node __sk_common.skc_node
#define sk_bind_node __sk_common.skc_bind_node
#define sk_refcnt __sk_common.skc_refcnt
unsigned char sk_shutdown : 2,
sk_no_check : 2,
sk_userlocks : 4;
unsigned char sk_protocol;
unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
struct xfrm_policy *sk_policy[2];
rwlock_t sk_dst_lock;
atomic_t sk_rmem_alloc;
atomic_t sk_wmem_alloc;
atomic_t sk_omem_alloc;
struct sk_buff_head sk_receive_queue;
struct sk_buff_head sk_write_queue;
int sk_wmem_queued;
int sk_forward_alloc;
unsigned int sk_allocation;
int sk_sndbuf;
int sk_route_caps;
int sk_hashent;
unsigned long sk_flags;
unsigned long sk_lingertime;
struct {
struct sk_buff *head;
struct sk_buff *tail;
} sk_backlog;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
struct ucred sk_peercred;
int sk_rcvlowat;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
int sk_write_pending;
void *sk_security;
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
void (*sk_error_report)(struct sock *sk);
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
};
struct sk_buff *head;
struct sk_buff *tail;
} sk_backlog;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
struct ucred sk_peercred;
int sk_rcvlowat;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
int sk_write_pending;
void *sk_security;
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
void (*sk_error_report)(struct sock *sk);
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
};
__sk_common是套接口在网络层的最小表示。下面是其定义:
struct sock_common {
unsigned short skc_family; /*地址族*/
volatile unsigned char skc_state; /*连接状态*/
unsigned char skc_reuse; /*SO_REUSEADDR设置*/
int skc_bound_dev_if;
struct hlist_node skc_node;
struct hlist_node skc_bind_node; /*哈希表相关*/
atomic_t skc_refcnt; /*引用计数*/
};
struct sock_common {
unsigned short skc_family; /*地址族*/
volatile unsigned char skc_state; /*连接状态*/
unsigned char skc_reuse; /*SO_REUSEADDR设置*/
int skc_bound_dev_if;
struct hlist_node skc_node;
struct hlist_node skc_bind_node; /*哈希表相关*/
atomic_t skc_refcnt; /*引用计数*/
};
sk_shutdown是一组标志位,SEND_SHUTDOWN and/or RCV_SHUTDOWN。
sk_userlocks, SO_SNDBUF and SO_RCVBUF。
sk_rcvbuf表示接收缓冲区的字节长度。
sk_rmem_alloc表示接收队列已提交的字节数。
sk_receive_queue表示接收的数据包的队列。
sk_wmem_alloc表示发送队列已提交的字节数。
sk_write_queue表示发送数据包的队列。
sk_sndbuf表示发送缓冲区的字节长度。
sk_flags,SO_LINGER (l_onoff),SO_BROADCAST,SO_KEEPALIVE,SO_OOBINLINE。
sk_prot是指定的域内部的协议处理函数集,它是套接口层跟传输层之间的一个接口,提供诸如bind, accept, close等操作。
sk_ack_backlog表示当前的侦听队列。
sk_max_ack_backlog表示最大的侦听队列。
sk_type表示套接字的类型,如SOCK_STREAM。
sk_protocol表示在当前域中套接字所属的协议。
几个函数指针均属回调函数,分别在套接口状态变化,有数据到达需要处理,有发送空间可用,有错误等时候被回调。最后一个函数sk_destruct在套接口释放时被回调。
sk_userlocks, SO_SNDBUF and SO_RCVBUF。
sk_rcvbuf表示接收缓冲区的字节长度。
sk_rmem_alloc表示接收队列已提交的字节数。
sk_receive_queue表示接收的数据包的队列。
sk_wmem_alloc表示发送队列已提交的字节数。
sk_write_queue表示发送数据包的队列。
sk_sndbuf表示发送缓冲区的字节长度。
sk_flags,SO_LINGER (l_onoff),SO_BROADCAST,SO_KEEPALIVE,SO_OOBINLINE。
sk_prot是指定的域内部的协议处理函数集,它是套接口层跟传输层之间的一个接口,提供诸如bind, accept, close等操作。
sk_ack_backlog表示当前的侦听队列。
sk_max_ack_backlog表示最大的侦听队列。
sk_type表示套接字的类型,如SOCK_STREAM。
sk_protocol表示在当前域中套接字所属的协议。
几个函数指针均属回调函数,分别在套接口状态变化,有数据到达需要处理,有发送空间可用,有错误等时候被回调。最后一个函数sk_destruct在套接口释放时被回调。
inet_create如何完成对socket的创建
2006年08月11日 星期五 下午 02:18
前面讲到在sys_socket函数中,有一步是调用net_families[family]->create完成最后的创建工作,下面就以inet域的创建来解释这最后一步的创建工作:
1、设socket->state = SS_UNCONNECTED。
2、从数组inetsw中匹配套接字类型和协议类型。inetsw是一个链表数组,也就是说数组的每一项是一个链表,同套接字类型的在同一个链表中。比如,用户这样创建一个TCP协议的套接字:
socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )
最终,内核在inetsw中匹配到的是这样一个结构体:
static struct inet_protosw inetsw_array[] =
{
{
.type = SOCK_STREAM,
.protocol = IPPROTO_TCP,
.prot = &tcp_prot,
.ops = &inet_stream_ops,
.capability = -1,
.no_check = 0,
.flags = INET_PROTOSW_PERMANENT,
}
}
这里最关键的是prot成员和ops成员,tcp_prot将提供TCP协议相关的全部操作,inet_stream_ops将提供域相关的全部操作,包括listen, connect等。
3、socket->ops = 匹配到的那个ops。
4、分配socket->sock。
5、让struct inet_sock指向socket->sock,struct inet_sock是struct sock的超集。其头部内容即为struct sock。
6、为inet_sock和socket->sock的成员赋初始值。这里,我们可以看到一些平时我们比较关心的问题,比如:inet->mc_ttl = 1。
7、调用socket->sock->sk_prot->init(...)完成整个创建过程。
最后,调用sock_map_fd找一个空闲的文件描述符,映射到这个创建好的套接字上,将这个文件描述符返回。
描述到这里,一个最为粗糙的socket创建过程算是完成了,但留下的问题却更多了,它涉及到很多宠大的结构体,其内容与socket的正常工作都息息相关,下文会陆续给出分析。
21:49
1、设socket->state = SS_UNCONNECTED。
2、从数组inetsw中匹配套接字类型和协议类型。inetsw是一个链表数组,也就是说数组的每一项是一个链表,同套接字类型的在同一个链表中。比如,用户这样创建一个TCP协议的套接字:
socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )
最终,内核在inetsw中匹配到的是这样一个结构体:
static struct inet_protosw inetsw_array[] =
{
{
.type = SOCK_STREAM,
.protocol = IPPROTO_TCP,
.prot = &tcp_prot,
.ops = &inet_stream_ops,
.capability = -1,
.no_check = 0,
.flags = INET_PROTOSW_PERMANENT,
}
}
这里最关键的是prot成员和ops成员,tcp_prot将提供TCP协议相关的全部操作,inet_stream_ops将提供域相关的全部操作,包括listen, connect等。
3、socket->ops = 匹配到的那个ops。
4、分配socket->sock。
5、让struct inet_sock指向socket->sock,struct inet_sock是struct sock的超集。其头部内容即为struct sock。
6、为inet_sock和socket->sock的成员赋初始值。这里,我们可以看到一些平时我们比较关心的问题,比如:inet->mc_ttl = 1。
7、调用socket->sock->sk_prot->init(...)完成整个创建过程。
最后,调用sock_map_fd找一个空闲的文件描述符,映射到这个创建好的套接字上,将这个文件描述符返回。
描述到这里,一个最为粗糙的socket创建过程算是完成了,但留下的问题却更多了,它涉及到很多宠大的结构体,其内容与socket的正常工作都息息相关,下文会陆续给出分析。
21:49
struct sock详解
结构体sock是套接口在网络层的表示,在代码include/net/sock.h 174行定义,下面是其内容:
struct sock {
struct sock_common __sk_common;
#define sk_family __sk_common.skc_family
#define sk_state __sk_common.skc_state
#define sk_reuse __sk_common.skc_reuse
#define sk_bound_dev_if __sk_common.skc_bound_dev_if
#define sk_node __sk_common.skc_node
#define sk_bind_node __sk_common.skc_bind_node
#define sk_refcnt __sk_common.skc_refcnt
unsigned char sk_shutdown : 2,
sk_no_check : 2,
sk_userlocks : 4;
unsigned char sk_protocol;
unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
struct xfrm_policy *sk_policy[2];
rwlock_t sk_dst_lock;
atomic_t sk_rmem_alloc;
atomic_t sk_wmem_alloc;
atomic_t sk_omem_alloc;
struct sk_buff_head sk_receive_queue;
struct sk_buff_head sk_write_queue;
int sk_wmem_queued;
int sk_forward_alloc;
unsigned int sk_allocation;
int sk_sndbuf;
int sk_route_caps;
int sk_hashent;
unsigned long sk_flags;
unsigned long sk_lingertime;
struct {
struct sk_buff *head;
struct sk_buff *tail;
} sk_backlog;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
struct ucred sk_peercred;
int sk_rcvlowat;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
int sk_write_pending;
void *sk_security;
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
void (*sk_error_report)(struct sock *sk);
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
};
struct sk_buff *head;
struct sk_buff *tail;
} sk_backlog;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
struct ucred sk_peercred;
int sk_rcvlowat;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
struct timer_list sk_timer;
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct page *sk_sndmsg_page;
struct sk_buff *sk_send_head;
__u32 sk_sndmsg_off;
int sk_write_pending;
void *sk_security;
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
void (*sk_error_report)(struct sock *sk);
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
};
__sk_common是套接口在网络层的最小表示。下面是其定义:
struct sock_common {
unsigned short skc_family; /*地址族*/
volatile unsigned char skc_state; /*连接状态*/
unsigned char skc_reuse; /*SO_REUSEADDR设置*/
int skc_bound_dev_if;
struct hlist_node skc_node;
struct hlist_node skc_bind_node; /*哈希表相关*/
atomic_t skc_refcnt; /*引用计数*/
};
struct sock_common {
unsigned short skc_family; /*地址族*/
volatile unsigned char skc_state; /*连接状态*/
unsigned char skc_reuse; /*SO_REUSEADDR设置*/
int skc_bound_dev_if;
struct hlist_node skc_node;
struct hlist_node skc_bind_node; /*哈希表相关*/
atomic_t skc_refcnt; /*引用计数*/
};
sk_shutdown是一组标志位,SEND_SHUTDOWN and/or RCV_SHUTDOWN。
sk_userlocks, SO_SNDBUF and SO_RCVBUF。
sk_rcvbuf表示接收缓冲区的字节长度。
sk_rmem_alloc表示接收队列已提交的字节数。
sk_receive_queue表示接收的数据包的队列。
sk_wmem_alloc表示发送队列已提交的字节数。
sk_write_queue表示发送数据包的队列。
sk_sndbuf表示发送缓冲区的字节长度。
sk_flags,SO_LINGER (l_onoff),SO_BROADCAST,SO_KEEPALIVE,SO_OOBINLINE。
sk_prot是指定的域内部的协议处理函数集,它是套接口层跟传输层之间的一个接口,提供诸如bind, accept, close等操作。
sk_ack_backlog表示当前的侦听队列。
sk_max_ack_backlog表示最大的侦听队列。
sk_type表示套接字的类型,如SOCK_STREAM。
sk_protocol表示在当前域中套接字所属的协议。
几个函数指针均属回调函数,分别在套接口状态变化,有数据到达需要处理,有发送空间可用,有错误等时候被回调。最后一个函数sk_destruct在套接口释放时被回调。
sk_userlocks, SO_SNDBUF and SO_RCVBUF。
sk_rcvbuf表示接收缓冲区的字节长度。
sk_rmem_alloc表示接收队列已提交的字节数。
sk_receive_queue表示接收的数据包的队列。
sk_wmem_alloc表示发送队列已提交的字节数。
sk_write_queue表示发送数据包的队列。
sk_sndbuf表示发送缓冲区的字节长度。
sk_flags,SO_LINGER (l_onoff),SO_BROADCAST,SO_KEEPALIVE,SO_OOBINLINE。
sk_prot是指定的域内部的协议处理函数集,它是套接口层跟传输层之间的一个接口,提供诸如bind, accept, close等操作。
sk_ack_backlog表示当前的侦听队列。
sk_max_ack_backlog表示最大的侦听队列。
sk_type表示套接字的类型,如SOCK_STREAM。
sk_protocol表示在当前域中套接字所属的协议。
几个函数指针均属回调函数,分别在套接口状态变化,有数据到达需要处理,有发送空间可用,有错误等时候被回调。最后一个函数sk_destruct在套接口释放时被回调。
更多推荐
已为社区贡献4条内容
所有评论(0)