内容摘录自极客时间课程《趣谈网络协议》,如有侵权,请及时联系删除。
零星知识点
MAC地址
MAC(Media Access Control,介质访问控制)地址,也叫硬件地址,长度是 48 比特(6 字节),由 16 进制的数字组成,分为前 24 位和后 24 位。前 24 位叫作组织唯一标志符(Organizationally Unique Identifier,OUI),是由 IEEE 的注册管理机构给不同厂家分配的代码,用于区分不同的厂家。后 24 位是厂家自己分配的,称为扩展标识符。同一个厂家生产的网卡中 MAC 地址后 24 位是不同的。
MAC 本来设计为唯一性的,但是后来设备越来越多,而且还有虚拟化的设备和网卡,有很多工具可以修改,就很难保证不冲突了。但是至少应该保持一个局域网内是唯一的。
MAC 地址是工作在一个局域网中的,因而即便出现了冲突,网络工程师也能够在自己的范围内很快定位并解决这个问题。
TCP包重复问题
TCP 重试机制下,TCP收到重复的包后,会进行去重,再发给应用层、HTTP 层。所以在同一个TCP连接下不会出现重复包都被应用层处理的问题。
但如果网络原因或者服务端错误,导致 TCP 连接断了,这样会重新发送应用层的请求,也即 HTTP 的请求会重新发送一遍。如果服务端设计的是无状态的,它记不住上一次已经发送了一次请求。如果处理不好,就会导致重复下单,这就需要服务端除了实现无状态,还需要根据传过来的订单号实现幂等,同一个订单只处理一次。还会有的现象是请求被黑客拦截,发送多次,这在 HTTPS 层可以有很多种机制,例如通过 Timestamp 和 Nonce 随机数联合起来,然后做一个不可逆的签名来保证。
IP和MAC的关系
IP 是有远程定位功能的,MAC 是没有远程定位功能的,只能通过本地 ARP 的方式找到。
网络层级之间的调用
在TCP/IP协议栈中的各层,下层的协议知道上层协议的,因为在每一层的包头里面,都会有上一层是哪个协议的标识,所以下层调上层不是通过回调函数,每一层的处理函数都会在操作系统启动的时候,注册到内核的一个数据结构里面,但是到某一层的时候,是通过判断到底是哪一层的哪一个协议,然后去找相应的处理函数去调用。
以UDP包为例:
发送:
- int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
- int ip_send_skb(struct net *net, struct sk_buff *skb)
- int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
- int neigh_output(struct neighbour *n, struct sk_buff *skb)
接收:
- int netif_receive_skb(struct sk_buff *skb)
- int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
- int ip_local_deliver(struct sk_buff *skb)
- int udp_rcv(struct sk_buff *skb)
其中,各层之间通过判断来确定接下来要调用的函数。