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);
};

猜你喜欢

转载自blog.csdn.net/weixin_45309916/article/details/120317887
今日推荐