通信工程tcp(2)期末复习_第1页
通信工程tcp(2)期末复习_第2页
通信工程tcp(2)期末复习_第3页
通信工程tcp(2)期末复习_第4页
通信工程tcp(2)期末复习_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、数据存储与字节序(1)什么是大端字节序:(2)什么是小端字节序:(3)什么是网络字节序:端模式分为:小端字节序和大端字节序,也就是字节在内存中的顺序。小端字节序:低字节存于内存低地址;高字节存于内存高地址。如一个long型数据0x123456780x0029f4580x780x0029f4590x560x0029f45a0x340x0029f45b0x12在以上数据存放于内存中的表现形式中,0x0029f458 < 0x0029f459 < 0x0029f45a < 0x0029f45b,可以知道内存的地址是由低到高的顺序;而数据的字节也是由低到高的,故以上字节序是小端字

2、节序。大端字节序:高字节存于内存低地址;低字节存于内存高地址。0x0029f4580x120x0029f4590x340x0029f45a0x560x0029f45b0x79在以上数据存放于内存中的表现形式中,0x0029f458 < 0x0029f459 < 0x0029f45a < 0x0029f45b,可以知道内存的地址是由低到高的顺序;而数据的字节却是由高到低的,故以上字节序是大端字节序。网络字节序:就是大端字节序。规定不同系统间通信一律采用网络字节序。在VC中的实验如下:int  temp = 0x12345678;调试中,该变量在内存中的字节数据是78

3、56 34 12,内存中的存放地址是:0x0029f458,0x0029f459,0x0029f45a,0x0029f45b;刚好符合低位存于低地址中,说明VC遵循小端字节序。二、Linux内核通用链表1、 内核通用链表的定义2、 怎样创建链表3、 怎样向链表添加元素4、 怎样从链表删除元素5、 怎样遍历链表6、 list_entry(.)宏的实现原理1、内核通用链表的定义 struct list_head   struct list_head *next, *prev; 2、  新建一个链表实

4、际上Linux只定义了链表节点,并没有专门定义链表头,那么一个链表结构是如何建立起来的呢?让我们来看看LIST_HEAD()这个宏:#define LIST_HEAD_INIT(name)      &(name), &(name) #define LIST_HEAD(name)      struct list_head name = LIST_HEAD_INIT(name)其中的name是struct list_head结构的变量的地址,而不是包

5、含struct list_head的数据结构的变量的地址3、 插入删除搬移合并a)插入对链表的插入操作有两种:在表头插入和在表尾插入。Linux为此提供了两个接口:static inline void list_add(struct list_head *new, struct list_head *head)static inline void list_add_tail(struct list_head *new, struct list_head *head)b) 删除static inline void list_del(struct list_

6、head *entry);c) 搬移Linux提供了将原本属于一个链表的节点移动到另一个链表的操作,并根据插入到新链表的位置分为两类:static inline void list_move(struct list_head *list, struct list_head *head);static inline void list_move_tail(struct list_head *list, struct list_head *head);d) 合并除了针对节点的插入、删除操作,Linux链表还提供了整个链表的插入功能:static inline void 

7、;list_splice(struct list_head *list, struct list_head *head);4、遍历      a) 由链表节点到数据项变量list_entry宏是用来根据list_head指针查找链表所嵌入的结构体的地址,具体实现是依赖宏container_of:#define list_entry(ptr, type, member)    container_of(ptr, type, member)#define container_of(ptr, type

8、, member)      ( const typeof( (type *)0)->member ) *_mptr = (ptr);                                 &#

9、160;                                         (type *)( (char *)_mptr - offsetof(type,member) );)#def

10、ine offsetof(type,  member)    (size_t) &(type *)0)-> member)      container_of有三个参数, ptr是成员变量的指针, type是指结构体的类型, member是成员变量的名字。 container_of 的作用就是在已知某一个成员变量的名字、指针和结构体类型的情况下,计算结构体的指针,也就是计算结构体的起始地址。 计算的方法其实很简单,就是用该成员变量的指针减去它于type结构体起始位置的偏移

11、量。在这个定义中,typeof( (type *)0)->member ) 就是获得 member 的类型, 然后定义了一个临时的常量指针 _mptr, 指向 member 变量。 把 _mptr 转换成 char * 类型, 因为 offsetof 得到的偏移量是以字节为单位。 两者相减得到结构体的起始位置, 再强制转换成 type 类型。     offsetof在这里,TYPE表示一个结构体的类型,MEMBER是结构体中的一个成员变量的名字。offsetof 宏的作用是计算成员变量 MEMBER 相对于结构体起始位置的内存偏移量,以字节(By

12、te)为单位。b) 遍历宏宏list_entry的定义如下: #define list_entry(ptr, type, member)  (type *)(char *)(ptr)-(unsigned long)(&(type *)0)->member) 1) (type *)0) 将0转型为type类型指针,这里就是list_user类型。 2) (type *)0)->member 访问结构

13、中的数据成员member,即list成员。 3) &(type *)0)->member) 取出数据成员member的地址,即list的地址。 4) (unsigned long)(&(type *)0)->member) 将上一步的地址进行类型转换得到一个unsigned long 型的数,也就是member所在结构实例的偏移地址,即得到list成员在list_user宿主中的偏移。 5) (char *)(ptr) 

14、;将宿主中list的地址转换为char *型,便于按字节进行计算。 6) ptr的值减去list在该宿主中的偏移,得到该宿主的首地址的值。 7) 对上一部的结果进行(type *)转型,获得宿主首地址,即list_user节点的地址。内核链表应用举例(可不看)双循环链表是linux内核常用的数据结构,这也是linux链表的一个非常有特色的地方。而涉及到链表的函数有链表的定义、链表头的初始化、链表的插入、链表的遍历、链表的删除和链表的回收。下面通过一个内核模块来说明链表的相关操作。#include <linux/kernel.h&

15、gt;#include <linux/module.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/list.h>MODULE_LICENSE("GPL");MODULE_AUTHOR("David Xie");MODULE_DESCRIPTION("List Module");MODULE_ALIAS("List module");/以上为内核模块的的头文件和模式固定的部分 s

16、truct student   char name100;   int num;   struct list_head list;/以上是定义包含有的struct list_head 结构的数据结构 struct student *pstudent;/定义一个结构数组,用来存放数据,注意这里pstudent是数组指针,数组的大小由后面的kmalloc来分配! struct student *tmp_student;/遍历时临时用来存放指向pstudenti的指针struct list_head stude

17、nt_list;/定义链表头(是一个节点)struct list_head *pos;/指向头结点的一个指针,会在list_for_each中说明 int mylist_init(void)   int i = 0;   INIT_LIST_HEAD(&student_list);/初始化链表头,注意参数是一个指针,用了&符号   pstudent = kmalloc(sizeof(struct student)*5,GFP_KERNEL);/为结构体数组分配空间,共有5个数组成员 

18、60; memset(pstudent,0,sizeof(struct student)*5);/初始化结构体数组   for(i=0;i<5;i+)/建立链表         sprintf(,"Student%d",i+1);/初始化并显示学生姓名      pstudenti.num = i+1; /初始化学生号码      list_a

19、dd( &(pstudenti.list), &student_list);/将pstudenti.list节点插入到student_list链表中,注意这里是从头结点处插入的,最后顺序为   5、4、3、2、1   list_for_each(pos,&student_list)/遍历链表,此函数指明pos是一个指向节点头的指针,前面已经定义了它的类型。遍历函数相当于一个for循环, 内为循环操作,没循环一次pos=&student_list+1!   tmp_student =&

20、#160;list_entry(pos,struct student,list);/list_entry(提取数据结构)指针pos指向结构体struct student中的成员list,返回值为指向list所在的结构体的指针(起始地址)   printk("<0>student %d name: %sn",tmp_student->num,tmp_student->name);/输出此结构体(结构数组其中的一个成员)的数据信息   return 0; void mylist_exit(void)/删除

21、节点    int i ;   for(i=0;i<5;i+)   list_del(&(pstudenti.list) );   kfree(pstudent);/释放分配的内存module_init(mylist_init);/内核模块模式固定的部分module_exit(mylist_exit);/内核模块模式固定的部分三、Linux内核通用哈希链表1、 内核通用哈希链表的定义2、 怎样创建哈希链表3、 怎样向哈希链表添加节点4、 怎样查找哈希链表5、 怎样删除哈希

22、链表节点6、 怎样全部输出哈希链表的所有节点1、内核通用哈希链表的定义 struct hlist_head   struct hlist_node *first;  struct hlist_node   struct hlist_node *next, *pprev;  2、怎样创建哈希链表 创建具有16个元素的哈希链表的方法如下:struct hlist_head user_hash

23、16;  3、怎样给哈希链表添加节点 (1)在指定的哈希链表头h所指向的链表头插入新节点 / n:要添加的新哈希链表节点 / h:在此哈希链表头节点后添加 hlist_add_head(struct hlist_node *n,  struct hlist_head *h);  4、怎样查找哈希链表 (2)根据当前哈希链表节点指针ptr获得哈希链表宿主节点指针 / ptr:struct hlist

24、_node类型的指针 / type:哈希链表节点所在的宿主节点的类型 / member:嵌入宿主的哈希链表节点的变量名 hlist_entry(ptr, type, member);  5、怎样删除哈希链表节点 (3)从链表中删除一个指定节点/ entry:要从链表中删除的节点 hlist_del(struct hlist_head *entry); 6、怎样全部输出哈希链表的所有节点 (4)遍历哈希链表中某个key值所对应的链表

25、60;/ tpos:哈希链表宿主节点指针 / pos:哈希链表节点指针 / head:哈希链表中某key所对应的链表的头指针 / member:嵌在哈希链表宿主节点中的哈希链表节点的变量名 hlist_for_each_entry(tpos, pos, head, member); 四、IP协议首部C语言定义首部各个字段的含义(参考教材P113-114)首都长度:IP首部的长度,一般为20B.版本:IP地址的版本,目前我们使用的都是第4版,所以这种IP也经常称为IPV4.服务

26、类型:服务类型包括一个3bit的优先权字段(现已被忽略),4bitTOS字段和1位未用位但必须置为0。4位的TOS分别代表最小延迟、最大吞吐量、最高可靠性和最小费用。对于TOS值,不同应用有不同的最佳值。具体值可参考RFC1394文档:/pdfrfc/rfc1349.txt.pdf总长度:数据包的总长度。该字段是IP首部的必要内容,因为链路层需要填充一些数据以达到最小长度。(PS:以太网的最小帧长为46B).标识符:唯一标识主机发送的每一份数据报。标志:分为3个字段,依次为保留位、不分片位和更多片位。 保留位:一般被置为0; 不分片位:表示该数据

27、报是否被分片,如果被置为1,则不能对数据报进行分片,如果要对其进行分片处理,就应将其置为0。 更多片位:除了最后一个分片,其他每个组成数据报的片都要讲该位置为1.片偏移:该分片相对于原始数据报开始处位置的偏移量。生存时间:设置数据报可以经过的最多路由器数,它指定了数据报的生存时间。生存时间由源主机指定,在数据报传输过程中,每经过一个路由器,该值就减1,当该字段的值为0时,数据报就会被丢弃,并发送ICMP报文通知源主机。协议:向IP层传输数据的协议类型,常见协议类型的值:表示1. ICMP协议表示2. IGMP协议3. 表示TCP协议4. 表示UDP协议首部许校验和:校验接收到的IP数据报是否有

28、差错。源IP地址:源主机的IP地址。目的IP地址:目的主机的IP地址。选项:该字段是数据报中的可选字段。这也是前面所说的IP首部长度一般为20B的原因。目前这个选项有如下定义:1)安全和处理限制(用于军事领域)2)记录路径3)时间戳4)宽松的源站选路5)严格的源站选路五、重点要掌握的内容IP报文分段原理及实现IP报文重组原理及实现(教材第9章中重点要理解的函数)append_data()msg_find()msg_frag_intern()msg_frag_queue()struct usermapstruct mfqstruct msg_hdr六、协议分析实例 0x0000

29、0; 00 1B 11 A6 BE 54 00 18-F3 DD 43 69 08 00 45 00 0x0010  00 20 D5 56 00 00 80 01-59 B2 C0 A8 00 8D CA 73 0x0020  80 2B

30、 08 00 1B 39 04 00-14 00 61 62 63 64 协议分析示例 -(1) 该以太帧源MAC地址和目的MAC地址分别是多少? 源MAC地址00 18 F3 DD 43 69  目的MAC地址00 1B 11 A6 BE 54 -(2)该以太帧的什么字节位置的值表示其承载的是IP报文? 第13、14

31、字节08 00 表示其是IP报文 -(3)该IP报文的头部有选项内容吗? 由头部长度ihl为5得知头部长度为最小20字节,所以没有选项内容。 -(4)该IP报文分段了吗,为什么? 由分段标识frag为000,得知该报文为可以分割的报文且后面没有报文,由片偏移为0 0000 0000 0000,得知这是第一个报文,所以得知这个报文没有被分割。-(5)该IP报文的头部和数据各是多少字节? 由头部长度ihl为5得知头部长度为5×4=20字节。总长度字段tot_len为0x 00&#

32、160;20 得总长度32字节。数据长度=总长度-(ihl×4)=12。 -(6)该IP报文的检验和按主机字节序表示,应是多少? 检验和check字段为59 B2,由于主机采用小端字节序,所以主机字节序为B2 59。 -(7)该IP报文的ID是多少? 由标识号D5 56 得知该报文ID为54614 -(8)该IP报文的服务类型(type of service)是多少? 由区分服务00 得知 服务类型是00.表示没有服务。七、内容提要in

33、t ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)    struct iphdr *iph;   if(skb->pkt_type=PACKET_OTHERHOST)(1)    goto drop; , if(!pskb_may_pul

34、l(skb,sizeof(struct iphdr)(2)   goto inhdr_error; iph = ip_hdr(skb); if(iph->ihl<5|iph->version!=4).(3)   goto inhdr_error; if(!pskb_may_pull(skb,iph->ihl*4)(4)   goto inhdr_error; iph =&#

35、160;ip_hdr(skb); if(unlikely(ip_fast_csum(u8*)iph, iph->ihl)   goto inhdr_error; len = ntohs(iph->tot_hen);.(5) if(skb->len<len).(6)    IP_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);    goto drop; else if(len<(iph->ihl*4)(7)   goto inhdr_error; if(pskb_trim_rcsum(skb,len)(8)   I

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论