第二章操作系统中的TCP/IP软件结构1进程问题:A进程概念:一个进程就是一次计算过程,并且独立于其他计算过程。B进程调度策略:CPU对没有被阻塞的进程赋予最高优先级,如多个进程优先级相同则在其中快速切换。C进程通信的三种机制:1.计数信号量——通用进程同步机制2.端口3.消息传递D生产者消费者问题:1.生产者生产数据报,放入数据报队列中,消费者从队列中提取数据报,消费数据。2.信号量初始化:S1=screate(N);//初始化生产者信号量S2=screate(0);//初始化消费者信号量生产者执行:wait(s1)………….Singal(s2)消费者执行:wait(s2)………….Singal(s1)3.队列全满时生产者阻塞,队列全空时消费者阻塞,其他情况两进程正常运行。E端口通信:端口:即消息队列,该队列有两个控制访问量,亦适用了信号量机制。端口全满psend()进程阻塞,全空precieve()阻塞。F消息传送:消息传送允许一个进程直接将消息发送给另外一个进程。进程通过send()发送消息,以进程标识号和一个消息做入口参数;receive()等待接收消息,它被阻塞直到某消息到达,调用send()函数的进程持续运行,连续两次调用send()无receive函数接收返回SYSERR,消息无法发送。可以调用recvclr()函数删除等待队列中的所有消息。2.数据传输问题A协议内部数据传输:一旦IP进程接受了一个传入数据报,它必须决定将其发往何处做进一步处理,根据其内容再将其交付给指定的进程。如:将数据交给TCP或UDP。B与操作系统数据传输:系统具有从各个网络接口读取分组的能力,为每一个网络硬件设备提供一个输入队列,当有分组到达时,发生中断并调用send()给IP进程发送消息,唯一的IP进程从所有队列中提取数据报进行处理。第三章网络接口层网络接口层:管理网络的硬件,完成从IP地址到硬件地址的映射过程,封装并发送分组,接收传入分组并将其发往对应的模块。网络接口的抽象模型,使得上层协议与硬件细节无关.A:伪网络接口问题:1使用的是0号还是1号?0号2为什么说伪网络接口在数据传输中有重要作用?伪网络接口既没有与之相关的设备驱动程序,也没有具体的硬件设施。发往伪网络接口的数据报将转交给本机的协议软件;当协议软件生成一个需要发送出去的数据报时,通过伪网络接口将此数据报传递给IP.设立伪网络接口的优点:1.消除了特殊情况的存在,简化了IP程序.2.使得本机在路由器表中的表示方法与其他目的站的表示方法完全一致.3.使得网络管理员能够像查询其它接口一样方便查询本地接口.B:如何通过网络接口地址求网络号?(P27~28页代码)/*ni_in.c传入分组的多路分解(2006.4.5)*///#includeconf.h#includekernel.h#includenetwork.h//#includeospf.hintarp_in(structnetif*,structep*);intrarp_in(structnetif*,structep*);intip_in(structnetif*,structep*);intni_in(structnetif*pni,structep*pep,unsignedlen){intrv;pep-ep_ifn=pni-&nif[0];//用当前端口的地址减去0端口的地址得到端口号答题重点pni-ni_ioctets+=len;//累加收到的总字节//判断是否为广播分组,累加相应的计数器if(!memcmp(pni-ni_hwa.ha_addr,pep-ep_dst,EP_ALEN))pni-ni_iucast++;//广播包elsepni-ni_inucast++;//非广播包//多路分解的实现switch(net2hs(pep-ep_type)){caseEPT_ARP:rv=arp_in(pni,pep);break;caseEPT_RARP:rv=rarp_in(pni,pep);break;caseEPT_IP:rv=ip_in(pni,pep);break;default://不是这三种协议,则抛弃包pni-ni_iunkproto++;free(pep);//用c库中的free释放,分配的时候也用mallocrv=OK;}returnrv;}第四章地址的发现与绑定ARP1,ARP高速缓存结构问题:A,为什么使用单一的高速缓存结构,它的优缺点如何?答:为了正确的阐述ARP协议规范,并且保证绑定正确且能满足高效性!优点:高速缓存分配能随网络动态的变化。缺点:网络接口的独立性较差,频繁使用的网络接口的绑定占据了大部分高速缓存时,高速缓存总是保持着100%的含量,查找到某表项的概率很小。B,ARP高速缓存结构问题?structarpentry{shortae_state;/*表现状态*/shortae_hwtype;/*硬件类型*/shortae_prtype;/*协议类型*/charae_hwlen;/*硬件地址长度*/charae_prlen;/*协议地址长度*/structnetif*ae_pni;/*接口结构指针*/intae_queue;/*此地址的包的队列*/intae_attempts;/*已发送绑定请求次数*/intae_ttl;/*生存值*/u_charae_hwa[MAXHWALEN];/*硬件地址*/u_charae_pra[MAXPRALEN];/*协议地址*/};ae_state具有三种状态AS_FREE此表项当前空闲,AS_PEDING此表项正在使用,但还未找到绑定,在此种状态中ae_attempts表示该表项请求分组被广播的次数;AS_RESOLVED状态表示此表项正在使用且绑定正确。ae_ttl表示在该表项需要被删除时还能保持多长时间。ae_quee指向分组队列,当相应的ARP相应分组到达后,队列中的分组被发送出去。在ARP高速缓存中,绑定的表项使用数组存储,对应的分组放入ae_quee指针指向的队列中。C,如何解决当一个IP请求mac时正在响应时,又有新的请求到达的问题?主要为理解P37~38页的代码,代码如下,调试部分已去除。#includeconf.h#includekernel.h#includenetwork.h#includeospf.hstructarpentry*arpalloc();structarpentry*arpfind(u_char*,u_short,structnetif*);intarpsend(structarpentry*);intlocal_out(structep*);intnetwrite(structnetif*pni,structep*pep,unsignedlen){structarpentry*pae;//arp表项指针STATWORDps;if(pni-ni_state!=NIS_UP){//判断网络接口状态,如果状态为关,则返回错误freebuf(pep);returnSYSERR;}pep-ep_len=len;disable(ps);pae=arpfind((u_char*)&pep-ep_nexthop,pep-ep_type,pni);//调用arpfind()函数,如果已绑定返回pae=1未绑定返回pae=0if(pae&&pae-ae_state==AS_RESOLVED){//处理已绑定情况memcpy(pep-ep_dst,pae-ae_hwa,pae-ae_hwlen);restore(ps);returnwrite(pni-ni_dev,pep,len);}if(IP_CLASSD(pep-ep_nexthop)){//判断是否为广播地址restore(ps);returnSYSERR;}if(pae==0){//处理未绑定状态pae=arpalloc();//回答本问题关键点,arpalloc()函数如后面所示pae-ae_hwtype=AR_HARDWARE;pae-ae_prtype=EPT_IP;pae-ae_hwlen=EP_ALEN;pae-ae_prlen=IP_ALEN;pae-ae_pni=pni;pae-ae_queue=EMPTY;memcpy(pae-ae_pra,&pep-ep_nexthop,pae-ae_prlen);pae-ae_attempts=0;pae-ae_ttl=ARP_RESEND;arpsend(pae);}if(pae-ae_queue==EMPTY)pae-ae_queue=newq(ARP_QSIZE,QF_NOWAIT);if(enq(pae-ae_queue,pep,0)0)freebuf(pep);restore(ps);returnOK;}arpalloc()函数如下#includeconf.h#includekernel.h#includeproc.h#includenetwork.hvoidarpdq(structarpentry*);structarpentry*arpalloc(){staticintaenext=0;structarpentry*pae;inti;for(i=0;iARP_TSIZE;++i){if(arptable[aenext].ae_state==AS_FREE)break;aenext=(aenext+1)%ARP_TSIZE;}pae=&arptable[aenext];aenext=(aenext+1)%ARP_TSIZE;if(pae-ae_state==AS_PENDING&&pae-ae_queue=0)//若表项处于AS_PENDING且分组队列大于0则调用arpdq(pae)删除一项并将下一项状态设为AS_PEDING,返回此时的AS_PEDINGarpdq(pae);pae-ae_state=AS_PENDING;returnpae;}综合上面代码:当有IP请求未完成时,若又有新请求到达,则先调用netwrite在newwrite()函数中先调用appalloc()在判定等待队列是否大于零,若大于零,则删除一项,返回下一项指针,然后将该项各属性赋值再次调用arpsend();发送请求,并将ae_attempts加1。2,arp高速缓存管理问题:A,arp旧表项删除Arp表项的删除是通过arpalloc();函数实现的,替换策略如下:在为arp高速缓存中的新成员分配空间时,如果存在空表项则选择空表项,不存在则采用循环法删除,即删除代码中静态整形变量aenext指向的项,并把aenext向后移动一个位置,以使下一轮查找跨过新添加的表项。代码注释如下:#includeconf.h#includekernel.h#includeproc.h#includenetwork.hvoidarpdq(structarpentry*);structarpentry*arpalloc(){staticintaenext=0;//静态整型变量,指向当缓存满时最先被替换的表项structarpentry*pae;//表项数组指针inti;for(i=0;iARP_TSIZE;++i){//搜索整个表项数组查找空闲if(arptable[aenext].ae_state==AS_FREE)break;//找到空闲则退出aenext=(aenext+1)%ARP_TSIZE;//未找到空闲则使表项前移一位}pae=&arptable[aenext];//将aenext指向的项设为替换对象aenext=(aenext+1)%ARP_TSIZE;//aenext前移一位if(pae-ae_state==AS_PENDING&&pae-ae_queue=0)arp