本文主要是介绍Ch1:概述,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、 概述
本章对Net/3网络代码的概述。
二、 网络实现概述
Net/3通过支持多种通信协议来提供通用的底层基础服务。4.4BSD支持四种不同的通信协议族:TCP/IP、XNS、OSI协议和Unix域协议。
内核对联网代码通过分层来组织,分为三层,如下图所示。
图1. Net/3联网代码分层结构
- 插口层是一个到下面协议相关层的协议无关接口。所有系统调用从协议无关的插口层开始。
- 协议层包括我们前面提到的四种协议族(TCP/IP,XNS,OSI和Unix域)的实现。
- 接口层包括同网络设备通信的设备驱动程序。
上图在各层间添加网络输入输出后的实现如下图2所示。
图2. 网络输入输出层间通信
三、 mbuf简介
mbuf, memory buffer简写。在整个联网代码中用于存储各种信息的数据结构。简单的mbuf数据结构图示。
图3. mbuf简单数据结构图示
更多关于mbuf的介绍见“Ch2:mbuf”。
四、 以太网输出
应用程序通过以太网发送UDP报文的输出流程如下图示。
图4. 三层处理一个简单UDP输出的执行过程
- 应用进程调用sendto系统调用。
- 插口层将插口地址结构复制到一个mbuf,并将sendto调用中指定的数据复制到一个或多个mbuf中。
- 协议层被调用,添加一个IP首部和一个UDP首部,调用IP输出例程。
- 以太网接口通过ARP学习48 bit以太网地址,并添加一个14字节的以太网首部至第一个mbuf中,接着将mbuf链表添加到接口的输出队列队尾,等待输出。
五、 以太网输入
输入处理与上述输出处理不同,因为输入是异步的。也即,它通过一个接收完成中断驱动以太网设备驱动程序来接收一个输入分组,而不是通过进程的系统调用。内核处理这个设备中断,并调度设备驱动程序进入运行状态。
以太网输入的处理流程如下:
- 以太网设备驱动程序处理中断,并将数据从设备读到一个mbuf链中。接着,以太网输入例程通过判断mbuf链中帧数据的类型字段把分组加入到IP输入队列中,同时产生一个软中断来执行IP输入例程。
- IP例程处理接收到的IP数据报,根据IP数据报头部信息(UDP输入)确定调用UDP输入例程来处理UDP数据报。
- UDP输入例程验证UDP首部各字段,然后选择一个进程来接收此数据报。
六、 中断与并发
我们从以太网输入可以看到网络代码处理输入分组用的是异步和中断驱动的方式。下面,介绍内核中定义的中断。
图5. 阻塞中断的内核函数说明
Net/3代码中经常调用函数splimp和splnet来阻止网络设备驱动程序中断的发生。具体来说,splimp把CPU的优先级升高到网络设备驱动程序级;而splx使处理器返回到原来的优先级。
七、 源代码组织
Net/3的网络源代码组织结构如下图(假设代码位于/usr/src/sys)。
图6. Net/3源代码目录
Net/3联网代码主要分布在:
- kern:通过的内核文件。
- net:通用联网文件。
- netinet:Internet协议代码:IP,ICMP,IGMP,TCP和UDP。
- sys:系统头文件。
八、 相关函数
8.1 sendto
功能:将数据由指定的socket传给对方主机。
原型:int sendto ( socket s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;
8.2 recvfrom
功能:接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间。
原型:ssize_t recvfrom(int sockfd,void *buf,int len,unsigned int flags, struct sockaddr *from,socket_t *fromlen);
8.3 bzero
功能:置字节字符串s的前n个字节为零且包括‘\0’。
原型:extern void bzero(void *s, int n);
8.4 socket
功能:创建socket套接字。
原型:int socket(int domain, int type, int protocol);
(完)
这篇关于Ch1:概述的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!