成都理工大学TCPIP实验报告.docx_第1页
成都理工大学TCPIP实验报告.docx_第2页
成都理工大学TCPIP实验报告.docx_第3页
成都理工大学TCPIP实验报告.docx_第4页
成都理工大学TCPIP实验报告.docx_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

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

文档简介

17本科生实验报告实验课程 计算机网络与TCP/IP协议体系(2) 学院名称 信息科学与技术学院 专业名称 通信工程 学生姓名 杜立华 学生学号 201313070112 指导教师 刘飚 实验地点 6B603 实验成绩 二 一五 年 二 月 二 一五 年 六 月实验一 Linux内核通用链表的使用 实验目的学习Linux内核通用链表的设计原理,熟练掌握Linux内核通用链表的使用。实验内容1、掌握Linux通用链表的创建2、掌握通用链表添加元素、删除元素和遍历链表的方法3、掌握通用链表的查找方法实验要求 待创建的链表头变量名为user_queue。 作为链表的宿主节点类型定义如下: struct user int id; /* user id */ struct list_head list; ; 针对上述user_queue链表,要求以队列方式向其中依次添加10个类型为struct user的宿主节点,并要求这10个宿主节点的id依次为110 依次遍历输出这10个宿主节点的id 从链表中删除首个宿主节点,然后依次遍历该队列并输出余下各宿主节点的id 在struct user结构体中增加一个username字段,用于存储该用户名字,重新以队列方式向其中依次添加10个类型为struct user的宿主节点,并要求这10个宿主节点的id依次为110 在链表中搜索id值为5的节点,并输出该节点username值实现原理Linux的内核源文件list.h提供了所有的链表定义,以及各类链表的操作接口和实现。其中创建链表的方法如下:LIST_HEAD(my_list); 源文件list.h中定义了如下若干接口,用于对通用链表进行各种操作: 在指定的head后插入新节点,常用于堆栈数据结构的实现/ newsk:即将添加的新链表节点/ head:在此节点后添加list_add(struct list_head *new, struct list_head *head); 在指定的head前插入新节点,常用于队列数据结构的实现/ newsk:即将添加的新链表节点/ head:在此节点前添加list_add_tail(struct list_head *new, struct list_head *head); 从链表中删除一个指定节点/ entry:要从链表中删除的节点list_del(struct list_head *entry); 根据当前链表节点指针ptr获得宿主节点指针/ ptr:struct list_head类型的指针/ type:链表节点所在的宿主节点的类型/ member:嵌入宿主的链表节点的变量名list_entry(ptr, type, member); 遍历链表/ pos:遍历链表时用于指示正在遍历的链表节点的指针/ head:链表头list_for_each(pos, head); 实现代码和运行结果请打印本实验的程序代码和程序运行截图,并作为附件附在本实验报告后。#include #include #include list.hstruct user int id; struct list_head list;int main(void) struct user *p; LIST_HEAD(user_queue); for (int i = 0; i id = i; list_add_tail(&p-list, &user_queue); struct list_head *q; list_for_each(q, &user_queue) p = list_entry(q, struct user, list); printf(%dn, p-id); return 0;#include #include #include list.hstruct user char username20; int id; struct list_head list;int main(void) struct user *p; LIST_HEAD(head); for (int i; i id = i + 1; printf(user %2d, Please input username: , i+1); scanf(%s, p-username); list_add_tail(&(p-list), &head); struct list_head *tmp; list_for_each(tmp, &head) p = list_entry(tmp, struct user, list); printf(%dt%sn, p-id, p-username); list_for_each(tmp, &head) p = list_entry(tmp, struct user, list); if (p-id = 5) printf(%sn, p-username); return 0;实验二 Linux内核通用哈希链表的使用 实验目的学习Linux内核通用哈希链表的设计原理,熟练掌握Linux内核通用哈希链表的使用。实验内容1、掌握Linux通用哈希链表的创建。2、掌握通用哈希链表添加元素、查找元素的方法。实验要求1、 待创建的哈希链表头数组为struct hlist_head user_hash16,要求对该哈希链表宿主节点的name成员值进行散列,并将散列值与15进行与运算作为哈希链表宿主元素的哈希值。2、 对该哈希表的所有表头元素进行初始化,初始化操作如下,其中index的变化范围为015。 INIT_HLIST_HEAD (&user_hashindex);3、 作为哈希链表元素的的宿主节点类型定义如下: struct usermap struct hlist_node hlist; unsigned char name8; ;4、 针对上述user_hash哈希链表,要求向其中添加3个类型为struct usermap的宿主节点,并要求这3个宿主节点的name成员分别为”smith”, ”john”, ”bob”, 如下图所示:struct usermapstruct hlist_head user_hash16struct hlist_node0.12.struct usermap155、 向哈希表user_hash中添加2个新宿主元素, 其中一个宿主元素的name成员为”john”,另外一个宿主元素的name成员为”lisa”。要求若新宿主元素的name成员已经存在,则提示已经存在该用户,不再向哈希链表中加入该已经存在的宿主节点,否则向哈希链表中添加该新宿主元素。6、 遍历整个哈希表,输出所有表中已存在的宿主节点元素的name。实现原理Linux的内核源文件list.h提供了哈希链表的各种操作接口和实现。其中创建具有16个元素的哈希链表的方法如下:struct hlist_head user_hash16; 在上述user_hash数组的16个元素中存放的哈希表头元素定义如下:struct hlist_head struct hlist_node *first;哈希链表节点元素定义如下:struct hlist_node struct hlist_node *next, *pprev;本实验对哈希链表宿主节点的name值进行散列的算法如下:unsigned int BKDRHash(unsigned char *str);unsigned int seed = 131;unsigned int hash = 0;while(*str) hash = hash * seed + (*str+); return (hash & 0x7FFFFFFF);于是,本实验对一个字符串name求最终哈希值hash的方法如下: unsigned int hash = BKDRHash(name) & 15; 内核源文件list.h定义了以下若干接口,用于对哈希链表进行各种操作:(1) 在指定的哈希链表头h所指向的链表头插入新节点/ n:要添加的新哈希链表节点/ h:在此哈希链表头节点后添加hlist_add_head(struct hlist_node *n, struct hlist_head *h); (2) 根据当前哈希链表节点指针ptr获得好像链表宿主节点指针/ ptr:struct hlist_node类型的指针/ type:哈希链表节点所在的宿主节点的类型/ member:嵌入宿主的哈希链表节点的变量名hlist_entry(ptr, type, member); (3) 遍历哈希链表中某个key值所对应的链表/ tpos:哈希链表宿主节点指针/ pos:哈希链表节点指针/ head:哈希链表中某key所对应的链表的头指针/ member:嵌在哈希链表宿主节点中的哈希链表节点的变量名hlist_for_each_entry(tpos, pos, head, member); 实现代码和运行结果请打印本实验的程序代码和程序运行截图,并作为附件附在本实验报告后。#include #include #include list.hstruct usermap struct hlist_node hlist; unsigned char name8;void hlist_print(struct hlist_head *hl_head);unsigned int BKDRHash(unsigned char *str);unsigned char hash_add(struct hlist_node *hl_node, struct hlist_head *hl_head);int main(void) struct hlist_head user_hash16; for (int i = 0; i 16; i+) INIT_HLIST_HEAD(&user_hashi); struct usermap user3; strcpy(, smith); strcpy(, john); strcpy(, bob); for (int i = 0; i 3; i+) hlist_add_head(&(useri.hlist), &user_hashBKDRHash() & 15); hlist_print(user_hash); struct usermap new_user2; strcpy(new_, john); strcpy(new_, lisa); for (int i = 0; i 2; i+) if (!hash_add(&(new_useri.hlist), &user_hashBKDRHash(new_) & 15) printf(用户%s重复,添加失败!n, new_); hlist_print(user_hash); return 0;void hlist_print(struct hlist_head *hl_head) struct usermap *puser; struct hlist_node *phnode; for (int i = 0; i name); printf(n); unsigned int BKDRHash(unsigned char *str) unsigned int seed = 131; unsigned int hash = 0; while(*str) hash = hash * seed + (*str+); return (hash & 0x7FFFFFFF);unsigned char hash_add(struct hlist_node *hl_node, struct hlist_head *hl_head) char *name = hlist_entry(hl_node, struct usermap, hlist)-name; struct usermap *puser; struct hlist_node *pnode; hlist_for_each_entry(puser, pnode, hl_head, hlist) if (!strcmp(puser-name, name) return 0; hlist_add_head(hl_node, hl_head); return 1;实验三 Linux多线程程序设计实验目的学习Linux下多线程程序的编写,掌握IP报文分段重组模拟程序的整体框架。实验内容 完成Linux下多线程的程序编写,利用线程同步的方法,完成多线程访问一个由Linux内核通用链表所实现的消息队列。实验要求7、 待创建的消息队列名为msg_queue。8、 作为消息队列的消息宿主节点类型定义如下: struct msg_buff int id; struct list_head list; ;9、 针对上述msg_queue队列,要求创建两个线程1和线程2,其中线程1向该队列尾逐步添加10个类型为struct msg_buff的宿主节点,并要求者10个宿主节点的id分别为110。另外,在线程1向该队列添加宿主节点的同时,要求线程2从该队列头部依次取出下一个宿主节点,并输出该节点的id值。实现原理线程模型本实验要求创建两个线程,分别为由main函数代表的线程1和由run函数代表的线程2。其中线程1模拟从网络持续接收消息,并将收到的消息放入消息队列中;线程2模拟网络协议处理程序,当消息队列不空时,持续从消息队列头取出下一个收到的消息并进行处理,如下图所示:消息队列mutex线程1线程2线程互斥与同步方法由于消息队列是一临界资源,线程1和线程2将竞争访问该队列,因此必须对线程1和线程2进行互斥与同步管理。即当线程1正在向消息队列尾放入消息时,线程2必须等待线程1操作完毕并退出对临界资源的操作后,方可以从该队列头部中取出下一个消息进行处理,反之亦然。此外,当消息队列为空时,线程2将进入休眠状态,当消息队列不空时,线程2被线程1唤醒后继续处理。下面给出实现线程1和线程2互斥与同步的部分关键代码。/* 定义访问临界资源的互斥变量 */pthread_mutex_t mqlock = PTHREAD_MUTEX_INITIALIZER;/* 定义条件变量 */pthread_cond_t mqlock_ready = PTHREAD_COND_INITIALIZER;/ * 线程1 */int main() struct msg_buff *msg; for(;) . pthread_mutex_lock(&mqlock); /* 加锁互斥量 */ list_add_tail(msg-list, &msg_queue); /* 消息入队列尾 */ pthread_mutex_unlock(&mqlock); /* 解锁互斥量 */ /* 通知线程2条件发生改变 */ pthread_cond_signal(&mqlock_ready); . . return 0;/ * 线程2 */void *run(void *arg) struct msg_buff *msg; for(;) pthread_mutex_lock(&mqlock); /* 加锁互斥量 */ while(list_empty(&msg_queue) /* 消息队列空,休眠等待条件改变 */ pthread_cond_wait(&mqlock_ready, &mqlock); /* 消息队列不空,从队列中取下一消息 */ msg = getnextmsg(msg_queue.next); /* 解锁互斥量 */ pthread_mutex_unlock(&mqlock); /* 处理此消息 */ handle_msg(msg); 实现代码和运行结果请在本实验所提供的代码msg.c的基础上,完成其中的add_msg和getnextmsg函数的实现;打印本实验的程序代码和程序运行截图,并作为附件附在本实验报告后面。#include #include #include #include #include list.h#define PAUSE 3000void *run(void *); /* 消息处理线程 */void add_msg(int);struct msg_buff *getnextmsg(struct list_head *);void handle_msg(struct msg_buff *);struct msg_buff int id; struct list_head list;/* 线程互斥量 */pthread_mutex_t mqlock = PTHREAD_MUTEX_INITIALIZER; /* 条件变量 */pthread_cond_t mqlock_ready = PTHREAD_COND_INITIALIZER; pthread_t tid; /* 消息处理线程id */LIST_HEAD(msg_queue); /* 消息队列 */int main() int err = 0; err = pthread_create(&tid, NULL, run, NULL);/* 创建并启动消息处理线程 */ for(int i = 0; i id = i; pthread_mutex_lock(&mqlock); list_add_tail(&new_msg-list, &msg_queue); pthread_mutex_unlock(&

温馨提示

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

评论

0/150

提交评论