广工大计算机网络FTP实验报告.docx
《广工大计算机网络FTP实验报告.docx》由会员分享,可在线阅读,更多相关《广工大计算机网络FTP实验报告.docx(43页珍藏版)》请在冰豆网上搜索。
广工大计算机网络FTP实验报告
课程设计
课程名称计算机网络
题目名称ping程序
Ftp程序
学生学院 自动化学院
专业班级 网络工程
学号 3110001381
学生姓名 何宇航
2014年1月
一:
PING程序设计
摘要:
该程序的核心为ping程序,通过ping程序来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。
ping使用的是ICMP协议,主要流程为:
它发送ICMP回送请求消息给目的主机,ICMP协议规定,目的主机必须返回ICMP回送应答消息给源主机,如果源主机在一定时间内收到应答,则认为主机可达。
若传送IP数据包发生错误--比如主机不可达,路由不可达等等,ICMP协议将会把错误信息封包,然后传送回给主机。
给主机一个处理错误的机会,这也就是为什么说建立在IP层以上的协议是可能做到安全的原因。
ICMP数据包由8bit的错误类型和8bit的代码和16bit的校验和组成。
而前16bit就组成了ICMP所要传递的信息。
关键词:
pingICMP协议IP
1具体设计任务
1.1实验目的
PING程序是我们使用的比较多的用于测试网络连通性的程序。
PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。
由计算机网络课程知道,ICMP是基于IP的一个协议,ICMP包通过IP的封装之后传递。
课程设计中选取PING程序的设计,其目的是希望同学们通过PING程序的设计,能初步掌握TCP/IP网络协议的基本实现方法,对网络的实现机制有进一步的认识。
1.2实验内容和要求
1.2.1RAW模式的SOCKET编程
PING程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。
为了实现直接对IP和ICMP包进行操作,实验中使用RAW模式的SOCKET编程。
熟悉SOCKET的编程,包括基本的系统调用如SOCKET、BIND等;
1.2.2具体内容
1)定义数据结构
需要定义好IP数据报、ICMP包等相关的数据结构;
2)程序实现
在WINDOWS环境下实现PING程序;
3)程序要求
在命令提示符下输入:
PINGΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ
其中ΧΧΧ为目的主机的IP地址,不要求支持域名,对是否带有开关变量也不做要求。
不带开关变量时,要求返回4次响应。
返回信息的格式:
REPLYFROMΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ
或
REQUESTTimeOut(无法PING通的情况)。
2.3实验主要仪器设备和材料
联网计算机
3基本思路及设计方案
构造ICMP请求回应包,发送,接收回应,若超时,打印超时
3.1原理框图
3.2主要程序源代码
#include
#include
#include
#pragmacomment(lib,"ws2_32.lib")//导入库文件
#defineICMP_ECHOREPLY0//ICMP回应答复
#defineICMP_ECHOREQ8//ICMP回应请求
#defineREQ_DATASIZE32//请求数据报大小
#include
usingnamespacestd;
//定义IP首部格式
typedefstruct_IPHeader
{
u_charVIHL;//版本和首部长度
u_charToS;//服务类型
u_shortTotalLen;//总长度
u_shortID;//标识号
u_shortFrag_Flags;//片偏移量
u_charTTL;//生存时间
u_charProtocol;//协议
u_shortChecksum;//首部校验和
structin_addrSrcIP;//源IP地址
structin_addrDestIP;//目的地址
}IPHDR,*PIPHDR;
//定义ICMP首部格式
typedefstruct_ICMPHeader
{
u_charType;//类型
u_charCode;//代码
u_shortChecksum;//首部校验和
u_shortID;//标识
u_shortSeq;//序列号
charData;//数据
}ICMPHDR,*PICMPHDR;
//定义ICMP回应请求
typedefstruct_ECHOREQUEST
{
ICMPHDRicmpHdr;
DWORDdwTime;
charcData[REQ_DATASIZE];
}ECHOREQUEST,*PECHOREQUEST;
//定义ICMP回应答复
typedefstruct_ECHOREPLY
{
IPHDRipHdr;
ECHOREQUESTechoRequest;
charcFiller[256];
}ECHOREPLY,*PECHOREPLY;
/**********************************************************************************/
//计算校验和
u_shortchecksum(u_short*buffer,intlen)
{
registerintnleft=len;
registeru_short*w=buffer;
registeru_shortanswer;
registerintsum=0;
//使用32位累加器,进行16位的反馈计算
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
//补全奇数位
if(nleft==1)
{
u_shortu=0;
*(u_char*)(&u)=*(u_char*)w;
sum+=u;
}
//将反馈的16位从高位移到低位
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return(answer);
}
/**********************************************************************************************/
//发送回应请求函数
intSendEchoRequest(SOCKETs,structsockaddr_in*lpstToAddr)
{
staticECHOREQUESTechoReq;
staticnId=1;
staticnSeq=1;
intnRet;
//填充回应请求消息
echoReq.icmpHdr.Type=ICMP_ECHOREQ;
echoReq.icmpHdr.Code=0;
echoReq.icmpHdr.Checksum=0;
echoReq.icmpHdr.ID=nId++;
echoReq.icmpHdr.Seq=nSeq++;
//填充要发送的数据
for(nRet=0;nRet{
echoReq.cData[nRet]='1'+nRet;
}
//存储发送的时间
echoReq.dwTime=GetTickCount();
//计算回应请求的校验和
echoReq.icmpHdr.Checksum=checksum((u_short*)&echoReq,sizeof(ECHOREQUEST));
//发送回应请求
nRet=sendto(s,(LPSTR)&echoReq,sizeof(ECHOREQUEST),
0,(structsockaddr*)lpstToAddr,sizeof(SOCKADDR_IN));
if(nRet==SOCKET_ERROR)
{
printf("sendto()error:
%d\n",WSAGetLastError());
}
return(nRet);
}
/*******************************************************************************/
//接收应答回复并进行解析
DWORDRecvEchoReply(SOCKETs,LPSOCKADDR_INlpsaFrom,u_char*pTTL)
{
ECHOREPLYechoReply;
intnRet;
intnAddrLen=sizeof(structsockaddr_in);
//接收应答回复
nRet=recvfrom(s,(LPSTR)&echoReply,sizeof(ECHOREPLY),
0,(LPSOCKADDR)lpsaFrom,&nAddrLen);
//检验接收结果
if(nRet==SOCKET_ERROR)
{
printf("recvfrom()error:
%d\n",WSAGetLastError());
}
//记录返回的TTL
*pTTL=echoReply.ipHdr.TTL;
//返回应答时间
return(echoReply.echoRequest.dwTime);
}
/********************************************************************************/
//等待回应答复,使用select模型
intWaitForEchoReply(SOCKETs)
{
structtimevaltimeout;
fd_setreadfds;
readfds.fd_count=1;
readfds.fd_array[0]=s;
timeout.tv_sec=1;
timeout.tv_usec=0;
return(select(1,&readfds,NULL,NULL,&timeout));
}
/******************************************************************************/
//PING功能实现
voidPing(char*pstrHost,boollogic)
{
SOCKETrawSocket;
LPHOSTENTlpHost;
structsockaddr_indestIP;
structsockaddr_insrcIP;
DWORDdwTimeSent;
DWORDdwElapsed;
u_charcTTL;
intnLoop,k=4;
intnRet,minimum=100000,maximum=0,average=0;
intsent=4,reveived=0,lost=0;
//创建原始套接字,ICMP类型
rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(rawSocket==SOCKET_ERROR)
{
printf("socket()error:
%d\n",WSAGetLastError());
return;
}
//检测目标主机
lpHost=gethostbyname(pstrHost);
if(lpHost==NULL)
{
printf("Hostnotfound:
%s\n",pstrHost);
return;
}
//设置目标机地址
destIP.sin_addr.s_addr=*((u_longFAR*)(lpHost->h_addr));//设置目标IP
destIP.sin_family=AF_INET;//地址规格
destIP.sin_port=0;
//提示开始进行PING
printf("\nPinging%s[%s]with%dbytesofdata:
\n",pstrHost,inet_ntoa(destIP.sin_addr),REQ_DATASIZE);
//发起多次PING测试
for(nLoop=0;nLoop{if(logic)k=k+1;
//发送ICMP回应请求
SendEchoRequest(rawSocket,&destIP);
//等待回复的数据
nRet=WaitForEchoReply(rawSocket);
if(nRet==SOCKET_ERROR)
{
printf("select()error:
%d\n",WSAGetLastError());
break;
}
if(!
nRet)
{
lost++;
printf("\nRequesttimeout.");
continue;
}
//接收回复
dwTimeSent=RecvEchoReply(rawSocket,&srcIP,&cTTL);
reveived++;
//计算花费的时间
dwElapsed=GetTickCount()-dwTimeSent;
if(dwElapsed>maximum)maximum=dwElapsed;
if(dwElapsedaverage+=dwElapsed;
printf("\nReplyfrom%s:
bytes=%dtime=%ldmsTTL=%d",
inet_ntoa(srcIP.sin_addr),REQ_DATASIZE,dwElapsed,cTTL);
}
printf("\n\n");
printf("Pingstatisticsfor%s:
\n",inet_ntoa(srcIP.sin_addr));
printf("Packets:
Sent=%d,Received=%d,Lost=%d(%.f%%loss),\n",
sent,reveived,lost,(float)(lost*1.0/sent)*100);
if(lost==0)
{printf("Approximateroundtriptimesinmilli-seconds:
\n");
printf("Minimum=%dms,Maximum=%dms,Average=%dms\n",minimum,maximum,average/sent);}
printf("\n\n");
nRet=closesocket(rawSocket);
if(nRet==SOCKET_ERROR)
{
printf("closesocket()error:
%d\n",WSAGetLastError());
}
}
//主程序
voidmain()
{
printf("WelcometothePingTest\n");
while
(1)
{
WSADATAwsd;//检测输入的参数
//初始化Winsock
if(WSAStartup(MAKEWORD(1,1),&wsd)!
=0)
{printf("加载Winsock失败!
\n");}
charopt1[100];
char*ptr=opt1;
boollog=false;
printf("Ping");
cin.getline(opt1,100,'\n');
if((opt1[0]=='-')&&(opt1[1]=='t'))
{log=true;ptr=opt1+3;}
//开始PING
Ping(ptr,log);
//程序释放Winsock资源
WSACleanup();
}
}
4实验结果
直接PINGIP地址,且PING通的情况下,返回四次响应。
如下图:
PING 域名
PING域名,若有丢包,如下图所示:
PING(域名前加-t,显示循环):
5遇到的问题及解决方法
调试时发现发送时间比预料中的长很多,经检查原来是函数中的符号“}”放置的位置过后。
6实验心得
通过这次的课程设计,加深了对网络协议的理解,一部机器想联网,必须遵守共同的通信约定(协议),才能正常同其他机器进行通信。
7思考题
1.本题目只要求实现PING的一些简单功能,在Windows命令行模式下,输入“Ping”回车,查看PING的所有功能,考虑如何实现这些功能。
答:
首先,Ping命令会构建一个固定格式的ICMP请求数据包,然后由ICMP协议将这个数据包连同地址“192.168.1.2”一起交给IP层协议(和ICMP一样,实际上是一组后台运行的进程),IP层协议将以地址“192.168.1.2”作为目的地址,本机IP地址作为源地址,加上一些其他的控制信息,构建一个IP数据包,并在一个映射表中查找出IP地址192.168.1.2所对应的物理地址(也叫MAC地址,熟悉网卡配置的朋友不会陌生,这是数据链路层协议构建数据链路层的传输单元——帧所必需的),一并交给数据链路层。
后者构建一个数据帧,目的地址是IP层传过来的物理地址,源地址则是本机的物理地址,还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。
2.如果一台主机能ping通自己但网络不通,可能是什么原因?
答:
(1)Windows服务器的网络服务功能还没启动
(2)计算机的TCP/IP协议没有与网卡有效的绑定;(3)可能计算机的网卡安装不正确,也可能是没连通;
3.考虑Netstat、Traceroute、ipconfig等网络测试应用程序的工作原理以及使用。
答:
Netstat的工作原理及使用:
(1)显示本地或与之相连的远程机器的连接状态,包括TCP、IP、UDP、ICMP协议的使用情况,了解本地机开放的端口情况.
(2)检查网络接口是否已正确安装,如果在用netstat这个命令后仍不能显示某些网络接口的信息,则说明这个网络接口没有正确连接,需要重新查找原因。
(3)通过加入“-r”参数查询与本机相连的路由器地址分配情况。
(4)检查一些常见的木马等黑客程序,因为任何黑客程序都需要通过打开一个端口来达到与其服务器进行通信的目的。
Traceroute程序的设计是利用ICMP及IPheader的TTL(TimeToLive)。
首先,traceroute送出一个TTL是1的IP数据报到目的地,当路径上的第一个路由器(router)收到这个数据报时,它将TTL减1。
此时,TTL变为0了,所以该路由器会将此数据报丢掉,并送回一个「ICMPtimeexceeded」消息,traceroute收到这个消息后,便知道这个路由器存在于这个路径上,接着traceroute再送出另一个TTL是2的datagram,发现第2个路由器......traceroute每次将送出的数据报的TTL加1来发现另一个路由器,这个重复的动作一直持续到某个数据报抵达目的地。
当数据报到达目的地后,该主机并不会送回ICMPtimeexceeded消息,因为它已是目的地了。
Ipconfig的工作原理及使用:
(1)查找目标主机的IP地址及其它有关TCP/IP协议的信息。
(2)当用户的网络中设置的是DHCP(动态IP地址配置协议)时,利用Ipconfig/winipcfg可以让用户很方便地了解到所用IPconfig/winipcfg机的IP地址的实际配置情况。
因为它有一个“/all”这个参数,所以它可侦查到本机上所有网络适配的IP地址分配情况,比ping命令更为详细。
如果我们一台IP地址为192.168.2.199上运行”Ipconfig”命令后,窗口中显示了主机名、DNS服务器、节点类型以及主机的相关信息如网卡类型、MAC地址、IP地址、子网掩码以及默认网关等。
其中网络适配器的MAC地址在检测网络错误时非常有用。
配置不正确的IP地址或子网掩码是接口配置的常见故障。
其中配置不正确的IP地址有两种情情况:
(1)网号部分不正确。
此时执行每一条Ipconfig命令都会显示“noanswer”,这样,执行该命令后错误的IP地址就能被发现,修改即可。
(2)主机部分不正确。
如与另一主机配置的地址相同而引起冲突。
这种故障是当两台主机同时配置相同的IP地址时出现的间歇性的通信问题。
更换IP地址中的主机号部分,该问题即能排除。
二.FTP文件传输协议的简单设计和实现
摘要:
初始化套接字,使用TCP协议实现客户端对服务器的硬盘文件的访问,包括上传和下载。
关键词:
上传下载TCP套接字
1具体设计任务
1.1实验目的
文件传送是各种计算机网络都实现的基本功能,文件传送协议是一种最基本的应用层协议按照客户/服务器的模式进行工作,提供交互式的访问,是INTERNET使用最广泛的协议之一。
本实验的目的是,学会利用已有网络环境设计并实现简单应用层协议,掌握TCP/IP网络应用程序基本的设计方法和实现技巧。
1.2实验内容和要求
1.2.1实验内容
我们的计算机网络实验环境建立在TCP/IP网络体系结构之上。
各计算机除了安装TCP/IP软件外,还安装了TCP/IP开发系统。
实验室各计算机具备Windows环境中套接字socket的编程接口功能,可为用户提供全网范围的进程通信功能。
本实验要求学生利用这些功能,设计和实现一个简单的文件传送协议。
1.2.2具体要求
用socket编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),该程序应能实现下述命令功能:
get:
取远方的一个文件
put:
传给远方一个文件
pwd:
显示远主当前目录
dir:
列出远方当前目录
cd:
改变远方当前目录
?
:
显示你提供的命令
quit:
退出返回
这此命令的具体工作方式(指给出结果的形式)可以参照FTP的相应命令,有余力的同学可以多实现几个命令。
最后,写出实验报告。
1.3实验主要仪器设备和材料
联网计算机
2文件传输协议的实现原理
2.1基本思路及设计方案
FTP的基本思路为,客户端向服务器提交查看/下载文件的请求,服务器则一直作检查请求的活动,当检测到有请求时,则响应请求。
具体的功能如下:
服务器功能:
1)浏览本地目录、自动获取IP,将本地目录发送至客户端(客户端能够在相应位置显示)2)上传某文件至客户端
客户端功能
1)查看本地目录(将要下