计算机网络与TCPIP协议体系2.docx

上传人:b****3 文档编号:4926502 上传时间:2022-12-11 格式:DOCX 页数:16 大小:385.38KB
下载 相关 举报
计算机网络与TCPIP协议体系2.docx_第1页
第1页 / 共16页
计算机网络与TCPIP协议体系2.docx_第2页
第2页 / 共16页
计算机网络与TCPIP协议体系2.docx_第3页
第3页 / 共16页
计算机网络与TCPIP协议体系2.docx_第4页
第4页 / 共16页
计算机网络与TCPIP协议体系2.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

计算机网络与TCPIP协议体系2.docx

《计算机网络与TCPIP协议体系2.docx》由会员分享,可在线阅读,更多相关《计算机网络与TCPIP协议体系2.docx(16页珍藏版)》请在冰豆网上搜索。

计算机网络与TCPIP协议体系2.docx

计算机网络与TCPIP协议体系2

本科生实验报告

实验课程计算机网络与TCP/IP协议体系

(2)

学院名称信息科学与技术学院

专业名称

学生姓名

学生学号

指导教师

实验地点6B603

实验成绩

 

二〇一五年二月——二〇一五年六月

实验一Linux内核通用链表的使用

1、实验目的

学习Linux内核通用链表的设计原理,熟练掌握Linux内核通用链表的使用。

2、实验内容

1、掌握Linux通用链表的创建

2、掌握通用链表添加元素、删除元素和遍历链表的方法

3、掌握通用链表的查找方法

3、实验要求

待创建的链表头变量名为user_queue。

作为链表的宿主节点类型定义如下:

structuser{

intid;/*userid*/

structlist_headlist;

};

针对上述user_queue链表,要求以队列方式向其中依次添加10个类型为structuser的宿主节点,并要求这10个宿主节点的id依次为1—10

依次遍历输出这10个宿主节点的id

从链表中删除首个宿主节点,然后依次遍历该队列并输出余下各宿主节点的id

在structuser结构体中增加一个username字段,用于存储该用户名字,重新以队列方式向其中依次添加10个类型为structuser的宿主节点,并要求这10个宿主节点的id依次为1—10

在链表中搜索id值为5的节点,并输出该节点username值

实现代码和运行结果

#include

#include

#include"list.h"

structuser{

intid;

structlist_headlist;

};

intmain()

{

LIST_HEAD(user_queue);

structuseru[10];

structuser*p;

inti;

for(i=0;i<10;i++)

{

list_add_tail(&u[i].list,&user_queue);

u[i].id=i+1;

}

list_for_each_entry(p,&user_queue,list)

printf("userid%d\n",p->id);

return0;

}

2.#include

#include

#include"list.h"

structuser{

intid;

structlist_headlist;

};

intmain()

{

LIST_HEAD(user_queue);

structuseru[10];

structuser*p,*pdel;

inti;

for(i=0;i<10;i++)

{

list_add_tail(&u[i].list,&user_queue);

u[i].id=i+1;

}

pdel=&(u[0]);

list_del(&(pdel->list));

list_for_each_entry(p,&user_queue,list)

printf("userid%d\n",p->id);

return0;

}

3.#include

#include

#include

#include"list.h"

structuser{

intid;

charname[8];

structlist_headlist;

};

intmain()

{

LIST_HEAD(user_queue);

structuseru[10];

structuser*p;

inti;

for(i=0;i<10;i++)

{

list_add_tail(&u[i].list,&user_queue);

u[i].id=i+1;

printf("inputusername:

\n");

scanf("%s",u[i].name);

}

list_for_each_entry(p,&user_queue,list)

printf("userid%d,username%s\n",p->id,p->name);

printf("searchid:

\n");

inta;

structuser*pa;

scanf("%d",&a);

pa=&(u[a]);

printf("nameis%s\n",pa->name);

return0;

}

实验二Linux内核通用哈希链表的使用

1、实验目的

学习Linux内核通用哈希链表的设计原理,熟练掌握Linux内核通用哈希链表的使用。

2、实验内容

1、掌握Linux通用哈希链表的创建。

2、掌握通用哈希链表添加元素、查找元素的方法。

3、实验要求

1、待创建的哈希链表头数组为structhlist_headuser_hash[16],要求对该structusermap...structusermapstructhlist_node

哈希链表宿主节点

的name成员值进行散列,并将散列值与15进行与运算作为哈希链表宿主元素的哈希值。

2、对该哈希表的所有表头元素进行初始化,初始化操作如下,其中index的变化范围为0~15。

INIT_HLIST_HEAD(&user_hash[index]);

3、作为哈希链表元素的的宿主节点类型定义如下:

structusermap{

structhlist_nodehlist;

unsignedcharname[8];

};

4、针对上述user_hash哈希链表,要求向其中添加3个类型为structusermap的宿主节点,并要求这3个宿主节点的name成员分别为”smith”,”john”,”bob”,如下图所示:

5、向哈希表user_hash中添加2个新宿主元素,其中一个宿主元素的name成员为”john”,另外一个宿主元素的name成员为”lisa”。

要求若新宿主元素的name成员已经存在,则提示已经存在该用户,不再向哈希链表中加入该已经存在的宿主节点,否则向哈希链表中添加该新宿主元素。

6、遍历整个哈希表,输出所有表中已存在的宿主节点元素的name。

4、实现代码和运行结果

#include

#include

#include"list.h"

structusermap{

structhlist_nodehlist;

unsignedcharname[8];

};

voidhlist_print(structhlist_head*hl_head);

unsignedintBKDRHash(unsignedchar*str);

unsignedcharhash_add(structhlist_node*hl_node,structhlist_head*hl_head);

intmain(void)

{

structhlist_headuser_hash[16];

for(inti=0;i<16;i++)

INIT_HLIST_HEAD(&user_hash[i]);

structusermapuser[3];

strcpy(user[0].name,"smith");

strcpy(user[1].name,"john");

strcpy(user[2].name,"bob");

for(inti=0;i<3;i++)

hlist_add_head(&(user[i].hlist),&user_hash[BKDRHash(user[i].name)&15]);

hlist_print(user_hash);

structusermapnew_user[2];

strcpy(new_user[0].name,"john");

strcpy(new_user[1].name,"lisa");

for(inti=0;i<2;i++)

if(!

hash_add(&(new_user[i].hlist),&user_hash[BKDRHash(new_user[i].name)&15]))

printf("用户%s重复,添加失败!

\n",new_user[i].name);

hlist_print(user_hash);

return0;

}

voidhlist_print(structhlist_head*hl_head)

{

structusermap*puser;

structhlist_node*phnode;

for(inti=0;i<16;i++)

{

printf("%d\t",i);

hlist_for_each_entry(puser,phnode,&hl_head[i],hlist)

printf("%s\t",puser->name);

printf("\n");

}

}

unsignedintBKDRHash(unsignedchar*str)

{

unsignedintseed=131;

unsignedinthash=0;

while(*str){

hash=hash*seed+(*str++);

}

return(hash&0x7FFFFFFF);

}

unsignedcharhash_add(structhlist_node*hl_node,structhlist_head*hl_head)

{

char*name=hlist_entry(hl_node,structusermap,hlist)->name;

structusermap*puser;

structhlist_node*pnode;

hlist_for_each_entry(puser,pnode,hl_head,hlist)

{

if(!

strcmp(puser->name,name))

return0;

}

hlist_add_head(hl_node,hl_head);

return1;

}

实验三Linux多线程程序设计

1、实验目的

学习Linux下多线程程序的编写,掌握IP报文分段重组模拟程序的整体框架。

2、实验内容

完成Linux下多线程的程序编写,利用线程同步的方法,完成多线程访问一个由Linux内核通用链表所实现的消息队列。

3、实验要求

待创建的消息队列名为msg_queue。

作为消息队列的消息宿主节点类型定义如下:

structmsg_buff{

intid;

structlist_headlist;

};

针对上述msg_queue队列,要求创建两个线程1和线程2,其中线程1向该队列尾逐步添加10个类型为structmsg_buff的宿主节点,并要求者10个宿主节点的id分别为1—10。

另外,在线程1向该队列添加宿主节点的同时,要求线程2从该队列头部依次取出下一个宿主节点,并输出该节点的id值。

4、实现代码和运行结果

#include

#include

#include

#include

#include"list.h"

#definePAUSE3000

void*run(void*);/*消息处理线程*/

voidadd_msg(int);

structmsg_buff*getnextmsg(structlist_head*);

voidhandle_msg(structmsg_buff*);

structmsg_buff{

intid;

structlist_headlist;

};

/*线程互斥量*/

pthread_mutex_tmqlock=PTHREAD_MUTEX_INITIALIZER;

/*条件变量*/

pthread_cond_tmqlock_ready=PTHREAD_COND_INITIALIZER;

pthread_ttid;/*消息处理线程id*/

LIST_HEAD(msg_queue);/*消息队列*/

intmain()

{

interr=0;

err=pthread_create(&tid,NULL,run,NULL);/*创建并启动消息处理线程*/

for(inti=0;i<10;i++){

add_msg(i);/*向消息队列添加消息*/

sleep

(1);

}

return0;

}

voidadd_msg(inti)

{

//完成向队列添加消息代码

structmsg_buff*new_msg=(structmsg_buff*)malloc(sizeof(structmsg_buff));

new_msg->id=i;

pthread_mutex_lock(&mqlock);

list_add_tail(&new_msg->list,&msg_queue);

pthread_mutex_unlock(&mqlock);

pthread_cond_signal(&mqlock_ready);

}

void*run(void*arg)

{

structmsg_buff*msg;

for(;;){

//通过getnextmsg函数从队列中取下一消息

pthread_mutex_lock(&mqlock);

while(list_empty(&msg_queue))

pthread_cond_wait(&mqlock_ready,&mqlock);

msg=getnextmsg(&msg_queue);

pthread_mutex_unlock(&mqlock);

handle_msg(msg);/*处理消息*/

free(msg);

}

}

structmsg_buff*getnextmsg(structlist_head*q)

{

structmsg_buff*msg;

//完成从队列中取下一消息代码

msg=list_first_entry(q,structmsg_buff,list);

list_del(&msg->list);

returnmsg;

}

voidhandle_msg(structmsg_buff*m)

{

printf("m->id=%d\n",m->id);/*处理此分组*/

}

实验四IP报文分段重组模拟

1、实验目的

学习Linux内核IP报文分段和重组的原理,掌握IP报文分段重组模拟程序的关键实现方法。

2、实验内容

1、联调Forward而和Host程序,观察基于消息分段和重组的文件传输过程。

2、完成IP报文分段和重组程序中用户退出登录的功能实现。

3、实验要求

1、选定4台PC工作站,其中一台作为转发服务器Forwarder,两台作为文件传输的发送方Host,另外一台作为接收方Host。

2、每3人一组,参考教材《网络编程与分层协议设计—基于Linux平台实现》第9.10一节的说明,完成IP报文分段与重组模拟程序的编译,并将Forwarder和Host正确部署在上述4台工作站上,以实现不同Host之间的文件传输。

3、仔细阅读Host.c和Forwarder.c源文件中关于消息分段、再分段和分段重组函数的实现代码。

完成Host.c中app_do_exit函数的实现,要求当某个已登录Host退出后,其他仍在线用户的的在线用户列表中能去除该退出登录的用户名。

4、实验任务

(1)实现退出登录业务功能

请完成某个登录用户退出的功能实现,要求所有其他在线用户通过刷新用户登录列表,可以看到该退出登录用户已经下线。

(2)程序运行截图

5、实现代码和运行结果

intapp_

do_exit(structmsg_buff*p_mbuf,structapp_hdr*ah)

{structlist_head*pos;

structlogin_exit*p_exit;

structusermap*p_usrmap;

unsignedinthash;

structhlist_node*n;

charwho[NAMESIZE],ch;

charusers[HQ_HASHSZ];

intuser_no;

u8*where;

u32user_ip;

u32who_ip;

intFOUND=0;

intnum=1;

memset(users,0,HQ_HASHSZ);

where=users;

p_exit=(structlogin_exit*)ah;

pthread_mutex_lock(&usrlock);

if(more)goto

shortcut;

memcpy(who,p_exit->user,NAMESIZE);

hash=BKDRHash(who)&(HQ_HASHSZ1);

hlist_for_each_entry(p_usrmap,n,&user_hash[hash],hlist)

if(!

strcmp(p_usrmap->name,who))

{printf("Toruntheapp_do_exit!

\n");

list_move(&p_usrmap->list,&user_queue);

list_del(&p_usrmap->list);

hlist_del(&p_usrmap->hlist);}elsegotoout;shortcut:

printf("[0]MORE");

list_for_each(pos,&user_queue)

{p_usrmap=list_entry(pos,USERMAP,list);

memcpy(where,p_usrmap->name,NAMESIZE);

where+=NAMESIZE;

printf("[%d]%s",(++num)-1,p_usrmap->name);

}

pthread_mutex_unlock(&usrlock);

if(num)

{do{printf("\nChooseoneusertobeginFragmentation""exercise:

");

scanf("%d",&user_no);

while((ch=getchar())!

='\n');

if(user_no==0)

{gotoout;}

if(user_no>0&&user_no<=num-1)

break;}

while(user_no>num-1);

memcpy(who,users+NAMESIZE*(user_no-1),NAMESIZE);

who_ip=ip_find(who);

send_file(who_ip);

}out:

return0;

}

学生实验心得

通过实验课自己动手写代码、运行、检查错误,因此加深了对上课学习的内容的理解,明白了在学习的过程中,遇到不懂的要自己去搜索资料,不断思考,不断总结。

学会了一些简单的程序操作,比如通用链表和哈希链表的创建、添加、删除节点及遍历操作。

在实验一和实验二中了解到了内核链表和哈希链表之间的不同,在哈希链表中用了二级指针

,还有IP报文的分段与重组原理,在此实验中了解到了MTU的重要性。

学生(签名):

2015年6月18日

指导

教师

评语

 

成绩评定:

指导教师(签名):

年月日

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1