struct socket
struct socket
内核版本:2.6.2
socket在内核中的变现形式,也就是我们通常所说的表示层的体现。
struct socket {
socket_state state;
unsigned long flags;
struct proto_ops *ops;
struct fasync_struct *fasync_list;
struct file *file;
struct sock *sk;
wait_queue_head_t wait;
short type;
unsigned char passcred;
};
重要字段及其含义。
字段 | 含义 |
---|---|
socket_state state | 状态 |
unsigned long flags | socket标志 |
struct proto_ops *ops | socket操作函数集合 |
struct file *file | 应用层下的表示形式 |
struct sock *sk | 连接层的一个抽象 |
short type | socket的类型 |
wait_queue_head_t | 缓冲区 |
状态
typedef enum {
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;
字段 | 含义 |
---|---|
SS_FREE | 该socket还未分配 |
SS_UNCONNECTED | 未连向任何socket |
SS_CONNECTING | 正在接连状态 |
SS_CONNECTED | 已连接状态 |
SS_DISCONNECTING | 正在断开连接的过程中 |
该成员只对TCP socket有用,因为只有tcp是面向连接的协议,udp跟raw不需要维护socket状态。
socket操作函数集合
struct proto_ops {
int family;
struct module *owner;
int (*release) (struct socket *sock);
int (*bind) (struct socket *sock,
struct sockaddr *myaddr,
int sockaddr_len);
int (*connect) (struct socket *sock,
struct sockaddr *vaddr,
int sockaddr_len, int flags);
int (*socketpair)(struct socket *sock1,
struct socket *sock2);
int (*accept) (struct socket *sock,
struct socket *newsock, int flags);
int (*getname) (struct socket *sock,
struct sockaddr *addr,
int *sockaddr_len, int peer);
unsigned int (*poll) (struct file *file, struct socket *sock,
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len);
int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len,
int flags);
int (*mmap) (struct file *file, struct socket *sock,
struct vm_area_struct * vma);
ssize_t (*sendpage) (struct socket *sock, struct page *page,
int offset, size_t size, int flags);
};
协议栈中总共定义了三个strcut proto_ops类型的变量,分别是myinet_stream_ops, myinet_dgram_ops, myinet_sockraw_ops,对应流协议, 数据报和原始套接口协议的操作函数集.
在我们使用使用tcp或者udp等时候时,用的bind,listen,connect等都是上面的函数。
struct file *file
在我们应用层下,一个socket的表现形式就是一个fd,应为Linux中一切皆为文件,有了文件系统的支持,我们就可以对socket抽象成的fd进行open,write,read等操作。
struct sock *sk
/**
* struct sock - network layer representation of sockets
* @__sk_common - shared layout with tcp_tw_bucket
* @sk_zapped - ax25 & ipx means !linked
* @sk_shutdown - mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN
* @sk_use_write_queue - wheter to call sk->sk_write_space in sock_wfree
* @sk_userlocks - %SO_SNDBUF and %SO_RCVBUF settings
* @sk_lock - synchronizer
* @sk_rcvbuf - size of receive buffer in bytes
* @sk_sleep - sock wait queue
* @sk_dst_cache - destination cache
* @sk_dst_lock - destination cache lock
* @sk_policy - flow policy
* @sk_rmem_alloc - receive queue bytes committed
* @sk_receive_queue - incoming packets
* @sk_wmem_alloc - transmit queue bytes committed
* @sk_write_queue - Packet sending queue
* @sk_omem_alloc - "o" is "option" or "other"
* @sk_wmem_queued - persistent queue size
* @sk_forward_alloc - space allocated forward
* @sk_allocation - allocation mode
* @sk_sndbuf - size of send buffer in bytes
* @sk_flags - %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings
* @sk_no_check - %SO_NO_CHECK setting, wether or not checkup packets
* @sk_debug - %SO_DEBUG setting
* @sk_rcvtstamp - %SO_TIMESTAMP setting
* @sk_no_largesend - whether to sent large segments or not
* @sk_route_caps - route capabilities (e.g. %NETIF_F_TSO)
* @sk_lingertime - %SO_LINGER l_linger setting
* @sk_hashent - hash entry in several tables (e.g. tcp_ehash)
* @sk_pair - socket pair (e.g. AF_UNIX/unix_peer)
* @sk_backlog - always used with the per-socket spinlock held
* @sk_callback_lock - used with the callbacks in the end of this struct
* @sk_error_queue - rarely used
* @sk_prot - protocol handlers inside a network family
* @sk_err - last error
* @sk_err_soft - errors that don't cause failure but are the cause of a persistent failure not just 'timed out'
* @sk_ack_backlog - current listen backlog
* @sk_max_ack_backlog - listen backlog set in listen()
* @sk_priority - %SO_PRIORITY setting
* @sk_type - socket type (%SOCK_STREAM, etc)
* @sk_localroute - route locally only, %SO_DONTROUTE setting
* @sk_protocol - which protocol this socket belongs in this network family
* @sk_peercred - %SO_PEERCRED setting
* @sk_rcvlowat - %SO_RCVLOWAT setting
* @sk_rcvtimeo - %SO_RCVTIMEO setting
* @sk_sndtimeo - %SO_SNDTIMEO setting
* @sk_filter - socket filtering instructions
* @sk_protinfo - private area, net family specific, when not using slab
* @sk_slab - the slabcache this instance was allocated from
* @sk_timer - sock cleanup timer
* @sk_stamp - time stamp of last packet received
* @sk_socket - Identd and reporting IO signals
* @sk_user_data - RPC layer private data
* @sk_owner - module that owns this socket
* @sk_state_change - callback to indicate change in the state of the sock
* @sk_data_ready - callback to indicate there is data to be processed
* @sk_write_space - callback to indicate there is bf sending space available
* @sk_error_report - callback to indicate errors (e.g. %MSG_ERRQUEUE)
* @sk_backlog_rcv - callback to process the backlog
* @sk_destruct - called at sock freeing time, i.e. when all refcnt == 0
*/
struct sock {
/*
* Now struct tcp_tw_bucket also uses sock_common, so please just
* don't add nothing before this first member (__sk_common) --acme
*/
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
volatile unsigned char sk_zapped;
unsigned char sk_shutdown;
unsigned char sk_use_write_queue;
unsigned char sk_userlocks;
socket_lock_t sk_lock;
int sk_rcvbuf;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
rwlock_t sk_dst_lock;
struct xfrm_policy *sk_policy[2];
atomic_t sk_rmem_alloc;
struct sk_buff_head sk_receive_queue;
atomic_t sk_wmem_alloc;
struct sk_buff_head sk_write_queue;
atomic_t sk_omem_alloc;
int sk_wmem_queued;
int sk_forward_alloc;
unsigned int sk_allocation;
int sk_sndbuf;
unsigned long sk_flags;
char sk_no_check;
unsigned char sk_debug;
unsigned char sk_rcvtstamp;
unsigned char sk_no_largesend;
int sk_route_caps;
unsigned long sk_lingertime;
int sk_hashent;
struct sock *sk_pair;
/*
* The backlog queue is special, it is always used with
* the per-socket spinlock held and requires low latency
* access. Therefore we special case it's implementation.
*/
struct {
struct sk_buff *head;
struct sk_buff *tail;
} sk_backlog;
rwlock_t sk_callback_lock;
struct sk_buff_head sk_error_queue;
struct proto *sk_prot;
int sk_err,
sk_err_soft;
unsigned short sk_ack_backlog;
unsigned short sk_max_ack_backlog;
__u32 sk_priority;
unsigned short sk_type;
unsigned char sk_localroute;
unsigned char sk_protocol;
struct ucred sk_peercred;
int sk_rcvlowat;
long sk_rcvtimeo;
long sk_sndtimeo;
struct sk_filter *sk_filter;
void *sk_protinfo;
kmem_cache_t *sk_slab;
struct timer_list sk_timer;
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
struct module *sk_owner;
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);
};