本文已参与「新人创作礼」活动,一起开启掘金创作之路。
网络协议栈
协议分层(协议栈)
协议分为:
|_______应用层message(数据报文的格式)
|______传输层segment(解决进程接收数据&决定数据传输形式| 使用端口号)
|_____网络层packet(解决数据报文的跨局域网传输| 使用IP地址)
|____链路层frame(解决局域网链路问题| 使用MAC地址)
|___物理层bit(物理层屏蔽了物理层采用的传输介质,通信设备和通信技术的差异性,指定不同类型的物理协议,使得数据链路只需要考虑如何使用物理层的服务,而不用考虑物理层采用了那种传输介质)
网络数据报文封装格式为:[以太网头]+[IP头]+[TCP头]+[应用层数据报文]+[以太网尾]
典型协议:
|___应用层(HTTP,FTP,SMTP,SSH,Telnet,DNS,DHCP)
|___传输层(TCP,UDP)
|___网络层(ICMP[ping],IGMP,IP[v4,v6])
|___链路层(ARP,RARP)
PS:
1.
ICMP| IP Control Management Protocol
IGMP| IP Group Management Protocol
它们的存在就是为了辅助IP层工作的,ICMP处理IP层出错,IGMP可以帮助一个主机加入一个组播组。
2.
ARP 地址解析协议在OSI模型中位于LLC层;TCP/IP模型中位于网络层
网络设备
网络设备
|___交换机switching(交换机在同一时刻可进行多个端口对之间的数据传输)
|___防火墙Firewall(通常指硬件防火墙| 程序嵌入到芯片中以减少CPU负担)
|___网关gateway(工作在OSI网络层| 典型应用是网络专用服务器)
|___路由器Router(工作在OSI网络层| Brouter是网桥和路由器的合并)
|___网桥Bridge(工作在OSI数据链路层| 交换机就是网桥)
|___中继器Repeater(工作在OSI物理层| 集线器HUB是有多个端口的中继器)
PS:
连MAC都不知道的算第1层,例如已经死绝了的hub
只知道MAC不知道IP的算第2层,例如普通交换机
只知道IP不知道port(也就不管TCP还是UDP)的算第3层,例如普通路由器
知道IP还知道port的算第4层,例如 NAT
关心payload的算第7层,例如 http proxy
网络接口socket
内核源码 fs/net.h
struct socket {
socket_state state;
short type;
unsigned long flags;
struct socket_wq *wq;
struct file *file;
struct sock *sk;
const struct proto_ops *ops;//函数指针集合
};
参数1| socket_state
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;
参数2|
参数3|
参数4| socket_wq
struct socket_wq {
/* Note: wait MUST be first field of socket_wq */
wait_queue_head_t wait;
struct fasync_struct *fasync_list;
unsigned long flags; /* %SOCKWQ_ASYNC_NOSPACE, etc */
struct rcu_head rcu;
} ____cacheline_aligned_in_smp;
参数5|
参数6|
参数7| proto_ops
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, bool kern);
int (*getname) (struct socket *sock,
struct sockaddr *addr,
int peer);
__poll_t (*poll) (struct file *file, struct socket *sock,
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
#ifdef CONFIG_COMPAT
int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
#endif
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, unsigned int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
#ifdef CONFIG_COMPAT
int (*compat_setsockopt)(struct socket *sock, int level,
int optname, char __user *optval, unsigned int optlen);
int (*compat_getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
#endif
int (*sendmsg) (struct socket *sock, struct msghdr *m,
size_t total_len);
/* Notes for implementing recvmsg:
* ===============================
* msg->msg_namelen should get updated by the recvmsg handlers
* iff msg_name != NULL. It is by default 0 to prevent
* returning uninitialized memory to user space. The recvfrom
* handlers can assume that msg.msg_name is either NULL or has
* a minimum size of sizeof(struct sockaddr_storage).
*/
int (*recvmsg) (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);
ssize_t (*splice_read)(struct socket *sock, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, unsigned int flags);
int (*set_peek_off)(struct sock *sk, int val);
int (*peek_len)(struct socket *sock);
/* The following functions are called internally by kernel with
* sock lock already held.
*/
int (*read_sock)(struct sock *sk, read_descriptor_t *desc,
sk_read_actor_t recv_actor);
int (*sendpage_locked)(struct sock *sk, struct page *page,
int offset, size_t size, int flags);
int (*sendmsg_locked)(struct sock *sk, struct msghdr *msg,
size_t size);
int (*set_rcvlowat)(struct sock *sk, int val);
};