tcpip实验报告.docx

上传人:b****7 文档编号:9737335 上传时间:2023-02-06 格式:DOCX 页数:40 大小:27.88KB
下载 相关 举报
tcpip实验报告.docx_第1页
第1页 / 共40页
tcpip实验报告.docx_第2页
第2页 / 共40页
tcpip实验报告.docx_第3页
第3页 / 共40页
tcpip实验报告.docx_第4页
第4页 / 共40页
tcpip实验报告.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

tcpip实验报告.docx

《tcpip实验报告.docx》由会员分享,可在线阅读,更多相关《tcpip实验报告.docx(40页珍藏版)》请在冰豆网上搜索。

tcpip实验报告.docx

tcpip实验报告

 

TCP/IP技术实验指导书

李沁编写

 

专业网络工程

班级104

学号109074

姓名

指导教师李沁

 

安徽工业大学计算机学院

二○一三年六月

实验一熟悉Linux编程环境3

实验二实现Echo服客户端程序(UDP)8

实验三循环无连接服务器Echo的实现11

实验四循环的、面向连接服务器的实现16

实验五并发的、面向连接服务器的实现18

实验六单进程并发服务21

实验七并发客户端25

实验八多线程服务29

实验九预分配进程服务器33

 

1.实验总体目标

配合TCPIP技术课程的教学,加强学生对TCP/IP编程技术的理解,培养学生的实际编程能力。

2.实验课时分配

序号

实验项目

学时

试验类型

实验一

熟悉Linux编程环境

2

综合性

实验二

实现Echo服务客户端程序(UDP)

2

综合性

实验三

循环无连接服务器的实现

2

综合性

实验四

循环的、面向连接服务器的实现

2

综合性

实验五

并发的、面向连接服务器的实现

2

综合性

实验六

单进程并发服务

2

综合性

实验七

并发的客户端

2

综合性

实验八

多线程服务

2

综合性

实验九

预分配进程服务器

2

综合性

3.实验环境

开发工具:

gcc以及编辑器(gedit,vi)

操作系统:

Linux2.6以上

4.实验总体要求

●按照各项实验内容做实验,包括操作、观察、记录、分析,通过操作和观察获得直观印象,从获得的数据中分析网络协议的工作原理;

●每项实验均提交实验报告,实验报告的内容可参照实验的具体要求,但总体上应包括以下内容:

实验准备情况,实验记录,实验结果分析,算法描述,程序段,实验过程中遇到的问题以及对思考问题的解答等,实验目的、实验原理、实验步骤不需要写入实验报告中。

 

实验一熟悉Linux编程环境

【实验目的】

1.掌握gcc的基本使用方法。

2.掌握fork函数的使用方法。

3.掌握exeve函数的使用方法。

【实验原理】

一、gcc的基本编译命令

设定编译出的object档档名或是可执行档档名:

参数:

-oout_put_filename

说明:

指定编译出的档名为out_put_filename。

范例:

本例将程式码'test.c'编译成可执行档,并设定档名为'test'。

gcctest.c–otest

二、fork函数

父进程调用fork函数创建子进程,返回值分别为0和子进程的PID,前者返回给子进程,后者返回给父进程。

父子进程根据返回的PID确定将要继续执行的指令。

例:

intpid;

sum=0;

pid=fork();

if(pid!

=0){/*originalprocess*/

printf("Theoriginalprocessprintsthis.\n");

}

else{

printf("Thenewprocessprintsthis.\n");

三、execve函数

intexecve(

constchar*pathname,

char*constargv[],char*constenvp[]);

函数说明execve()用来执行参数filename字符串所代表的文件路径,第二个参数系利用数组指针来传递给执行文件,最后一个参数则为传递给执行文件的新环境变量数组。

 返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。

例:

#include

#include

intmain(intarg,char**args)

{

//char*name="/usr/bin/ls";

char*argv[]={"ls","-l","/cway-linux/source",NULL};

//传递给执行文件的参数数组,这里包含执行文件的参数

char*envp[]={0,NULL};//传递给执行文件新的环境变量数组

execve("/bin/ls",argv,envp);

}

【实验步骤】

一、

练习1:

编写一个并发程序,利用fork函数创建五个进程,让每一个进程打印出可用来分辨不同进程的信息。

练习2:

编写一个程序,利用execve函数改变进程执行的代码。

二、利用gcc编译程序

三、执行程序观察程序输出

 

试验一熟悉Linux编程环境

实验时间:

_____________成绩:

________________

练习1:

编写一个并发程序,利用fork函数创建五个进程,让每一个进程打印出可用来分辨不同进程的信息。

#include

#include

#include

intmain()

{

intpid,i;

i=0;

while(i<5)

{

i++;

if((pid=fork())==0)

{

printf("pid:

%d\n",getpid());

sleep(3);

break;

}

waitpid(pid,(int*)0,0);

printf("ppid:

%d\n",getpid());

}

return0;

}

运行结果:

练习2:

编写一个程序,利用execve函数改变进程执行的代码。

//execve.c

#include

#include

#include

intmain(intargc,char*argv[])

{

char*newargv[]={NULL,"you","me",NULL};

char*newenviron[]={NULL};

if(argc!

=2)

{

fprintf(stderr,"Usage:

%s\n",argv[0]);

exit(EXIT_FAILURE);

}

newargv[0]=argv[1];

execve(argv[1],newargv,newenviron);

perror("execve");

exit(EXIT_FAILURE);

}

//myecho.c

#include

#include

#include

intmain(intargc,char*argv[])

{

inti;

for(i=0;i

printf("argv[%d]:

%s\n",i,argv[i]);

return0;

}

运行:

./execvemyecho

结果:

cwjuneva@ubuntu:

~$geditexecve.c

cwjuneva@ubuntu:

~$geditmyecho.c

cwjuneva@ubuntu:

~$gcc-omyechomyecho.c

cwjuneva@ubuntu:

~$./execvemyecho

argv[0]:

myecho

argv[1]:

you

argv[2]:

me

 

实验二实现Echo服客户端程序(UDP)

【实验目的】

1.掌握客户端程序的基本结构

2.掌握如何形成socket地址

3.掌握在UDP的套接字上读写数据

【实验环境配置】

Linux,开启echo后台服务

【实验原理】

一、获取系统当前时间API:

#include

intgettimeofday(structtimeval*tv,structtimezone*tz);

保存时间的结构体

struttimeval{

longtv_sec;/*秒数*/

longtv_usec;/*微秒数*/};

例子:

#include

#include

intmain(){

structtimevaltpstart,tpend;

doubletimeuse;

inti=0;

gettimeofday(&tpstart,NULL);

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

printf("%d,i);

gettimeofday(&tpend,NULL);

timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;

timeuse/=1000000;

printf("processortimeis%lfs\n",timeuse);

return0;}

二、参阅教材6、7两章的代码理解客户端echo程序的结构以及相关socket系统调用

【实验步骤】

1.实现教材第7章练习第11题,对echo客户端程序进行改进,实现简单超时重传。

(可以利用alarm函数或者select函数)

2.启动系统后台echo服务,测试编写的程序能否与后台echo交互(127.0.0.1)

3.关闭后台echo服务,测试编写的程序能否重传(在标准输出上显示相邻重传之间的时间间隔)

实验二实现Echo服务客户端程序(UDP)

实验时间:

_____________

//client.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

intreadable_timeo(intfd,intsec)

{

fd_setrset;

structtimevaltv;

FD_ZERO(&rset);

FD_SET(fd,&rset);

tv.tv_sec=sec;

tv.tv_usec=0;

return(select(fd+1,&rset,NULL,NULL,&tv));//使用select函数实现简单超时重传

}

intmain(intargc,char**argv)

{

intsockfd,len,res,i;

structsockaddr_inaddress;

char*host;

structhostent*hostinfo;

structservent*servinfo;

charbuf[128],buf2[128];

intnsec=20;//timeout:

20s

structtimevaltpstart,tpend;

doubletimeuse;

if(argc==1)

host="localhost";

else

host=argv[1];

hostinfo=gethostbyname(host);

if(!

hostinfo)

{

fprintf(stderr,"nohost:

%s\n",host);

exit

(1);

}

servinfo=getservbyname("echo","udp");

if(!

servinfo)

{

fprintf(stderr,"noechoserver!

\n");

exit

(1);

}

sockfd=socket(AF_INET,SOCK_DGRAM,0);

address.sin_family=AF_INET;

address.sin_port=servinfo->s_port;

address.sin_addr=*(structin_addr*)*hostinfo->h_addr_list;

len=sizeof(address);

while(fgets(buf,128,stdin)!

=NULL)

{

for(i=0;i<2;i++)//juseonechancetoresend

{

if(i==1)//resend

{

printf("ReSend!

!

!

\n");

gettimeofday(&tpend,NULL);

timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;

timeuse/=1000000;

printf("resendtimeis%lfs\n",timeuse);

}

gettimeofday(&tpstart,NULL);

res=sendto(sockfd,buf,strlen(buf),0,(structsockaddr*)&address,len);

if(readable_timeo(sockfd,nsec)==0)

{

fprintf(stderr,"sockettimeout\n");

continue;

}

res=recvfrom(sockfd,buf2,128,0,(structsockaddr*)&address,&len);

buf2[res]=0;

fputs(buf2,stdout);

break;//sendsuccessfully,quit!

}

}

close(sockfd);

exit(0);

}

实验三循环无连接服务器Echo的实现

【实验目的】

1.掌握服务器程序套接字构造方法

2.掌握实现迭代服务的程序结构

【实验原理】

一、服务器端构造UDP套接字

constchar*service;//nameofservice

constchar*transport;//tcporudp

intqlen;//thesizeofrequestqueue

/*

*Arguments:

*service-serviceassociatedwiththedesiredport

*transport-transportprotocoltouse("tcp"or"udp")

*qlen-maximumserverrequestqueuelength

*/

{

structservent*pse;/*pointertoserviceinformationentry*/

structprotoent*ppe;/*pointertoprotocolinformationentry*/

structsockaddr_insin;/*anInternetendpointaddress*/

ints,type;/*socketdescriptorandsockettype*/

memset(&sin,0,sizeof(sin));

sin.sin_family=AF_INET;

sin.sin_addr.s_addr=INADDR_ANY;//localIPinterfacedeterminedbykernel

/*Mapservicenametoportnumber*/

if(pse=getservbyname(service,transport))

sin.sin_port=htons(ntohs((unsignedshort)pse->s_port)

+portbase);//portbaseisusedtopreventcollisionwithwell-knownports

elseif((sin.sin_port=htons((unsignedshort)atoi(service)))==0)

errexit("can'tget\"%s\"serviceentry\n",service);

/*Mapprotocolnametoprotocolnumber*/

if((ppe=getprotobyname(transport))==0)

errexit("can'tget\"%s\"protocolentry\n",transport);

/*thestructureofsockethasbeenfilledcompletelysofar*/

/*Useprotocoltochooseasockettype*/

if(strcmp(transport,"udp")==0)

type=SOCK_DGRAM;

else

type=SOCK_STREAM;

/*Allocateasocket*/

s=socket(PF_INET,type,ppe->p_proto);

if(s<0)

errexit("can'tcreatesocket:

%s\n",strerror(errno));

/*Bindthesocket*/

if(bind(s,(structsockaddr*)&sin,sizeof(sin))<0)

errexit("can'tbindto%sport:

%s\n",service,

strerror(errno));

if(type==SOCK_STREAM&&listen(s,qlen)<0)

errexit("can'tlistenon%sport:

%s\n",service,

strerror(errno));

returns;

二、获取socket信息的系统API

#include

intioctl(intfd,intrequest,.../*void*arg*/);

fd是文件描述符,request是希望对fd执行的操作,当要获取socket信息时为SIOCGIFCONF.当调用ioctl函数前,我们需要首先创建一个ifcong结构并初始化(对ifc_len赋以一个足够的长度),并将其地址作为ioctl函数的第三个参数。

下面是ifcong结构的定义:

structifconf{

intifc_len;/*sizeofbuffer,value-result*/

union{

caddr_tifcu_buf;/*inputfromuser->kernel*/

structifreq*ifcu_req;/*returnfromkernel->user*/

}ifc_ifcu;

};

下面是ifreq结构的定义:

#defineIFNAMSIZ16

structifreq{

charifr_name[IFNAMSIZ];/*interfacename,e.g.,"le0"*/

union{

structsockaddrifru_addr;

structsockaddrifru_dstaddr;

structsockaddrifru_broadaddr;

shortifru_flags;

intifru_metric;

caddr_tifru_data;

}ifr_ifru;

};

【实验步骤】

实现服务端程序,需满足:

1.无连接、循环服务。

2.利用实验二的客户端程序向服务器程序请求服务,每次收到请求时在本地终端上输出客户端的IP地址和本次服务的时间。

3.客户端多次请求服务,观察服务器对客户端的反馈和本地终端输出,判断是否正确实现迭代服务。

 

试验三循环无连接服务器Echo的实现

实验时间:

_____________

//server.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineMAXLINE128

intsockfd,flag=1;

voidclose_action(intsig)

{

printf("closethesockfd\n");

close(sockfd);

signal(SIGINT,SIG_DFL);

flag=0;

}

intmain()

{

structsockaddr_insin,sin_cli;

inttype,res,opt;

charmesg[MAXLINE],buf[MAXLINE];

socklen_tlen;

structsigactionact;

structtm*ptm;

inty,m,d,h,n,s;

longts;

//setthesignalaction

act.sa_handler=close_action;

sigemptyset(&act.sa_mask);

act.sa_flags=0;

memset(&sin,0,sizeof(sin));

sin.sin_family=AF_INET;

sin.sin_addr.s_addr=INADDR_ANY;

sin.sin_port=htons(45454);

sockfd=socket(AF_INET,SOCK_DGRAM,0);

if(sockfd<0)

{

fprintf(stderr,"can'tcreatesocket%s\n",strerror(errno));

exit

(1);

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

当前位置:首页 > 总结汇报 > 学习总结

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

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