计算机网络报告.doc_第1页
计算机网络报告.doc_第2页
计算机网络报告.doc_第3页
计算机网络报告.doc_第4页
计算机网络报告.doc_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

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

文档简介

精品文档.精品文档一、课程设计目的1. 加深对计算机网络通信的工作原理的理解。通过编写计算机程序实现、模拟网络的某些功能,使学生理解并掌握计算机网络的基本原理及工作过程。2. 实现应用程序进程跨网络的通信了解系统调用和应用编程接口基本知识,理解应用程序和操作系统之间传递控制权的机制,掌握套接字的创建和运用,通过socket系统调用实现跨网络通信。3. 提高网络编程和应用能力提高实际编程能力和灵活运用所学知识解决的能力。培养调查研究、查阅技术文献、资料、手册以及编写技术文档的能力,理论应用于实践的能力。2、 课程设计内容1. 网络聊天程序的设计与实现 了解Socket通信的原理,在此基础上编写一个聊天程序。2. Ping程序设计与实现了解ping程序的实现原理,并调试通过。3. 基于IP多播的网络会议程序(实现了局域网内多人聊天)4. Windows 下的网络嗅探器参照附录4 raw socket编程例子,设计一个可以监视网络的状态、数据流动情况以及网络上传输的信息的网络嗅探器。.三、网络聊天程序的设计与实现题目内容:参照附录1,了解Socket通信的原理,在此基础上编写一个聊天程序。服务器端编程的步骤:1.加载套接字库,创建套接字(WSAStartup()/socket());2.绑定套接字到一个IP地址和一个端口上;3.将套接字设定为监听模式等待连接请求(listen());4.请求到来后,接受链接请求,返回一个新的应对于此次链接的套接字(accept());5.返回套接字和客户端进行通信(Send()/Rec());6.返回,等待另一个连接请求;7.关闭套接字,关闭套接字库(closesocket()WSACleanup())。客户端编程步骤:1.加载套接字库,创建套接字(WSAStartup()/socket();2.向服务端发出链接请求(connect();3.和服务端进行通信(Send()/Recv();4.关闭套接字,关闭套接字库(closesocket()/WSACleanup()调试过程该程序是用c写的,首先,我先用c编写一个客户端和一个服务器端,代码主要是参照了实验说明书上的,在此基础上稍做了些修改,实现一个简单客户端与服务端通信。在实现过程中出现了问题,后来通过网上查资料和请教别ws2_32.lib时出现错误;还有由于我用的是TCP协议通讯,它一次只接收一次发送一次,我通过一个简单的多线程解决了该问题 四、Tracert与Ping程序设计与实现题目内容:参照附录2,了解Tracert程序的实现原理,并调试通过。然后参考Tracert程序和教材4.4.2节,编写一个Ping程序,并能测试本局域网的所有机器是否在线4.1设计步骤1. 熟悉IP及ICMP协议的工作机制。2. 熟悉RAW模式的SOCKET编程。3. 编写Ping的实现程序。4. 编译环境中需要包括的SOCKET库win2_32.lib。5. 调试并运行自己编写的Ping程序。4.2调试过程1.原题目二给的附录二,可以实现输入一个IP地址或者域名,可以查看跳站情况,但是该题目要求测试本局域网所有机器在线,在局域网内机器由交换机连接并不需要路由器跳转,所以可以减小跳转站点数目,和响应时间,通过循环输入局域网的Ip地址从而达到测试机器是否在线;2.关于获取IP地址采用方式:获取ip最后一个字段-自增加一-将获得的ip字段-与该局域网内前三个字段连接-将得到的String 转化为所需要的char类型3.将获得的char类型放入到循环中,依次跳站4.需注意的是:由于是查找本局域网里的机器状态,只需要经过交换机来交换信息,不用跳站到路由器,所以需要将最大跳站30次减小,也需要将响应时间降低。避免长时间延迟。5.自己改变的代码部分:/获取Ip地址的最后一个字段int getIp(char Address) int count =1; int i, len = strlen(Address); for(i = 0; i len & count 4; i+) if(Addressi = .) count+; int ip = 0; for(; i len; i+) ip = ip * 10 + (Addressi - 0); return ip;/int 转 string 类型string intToString(int v)stringstream s; sv; string str = s.str(); return str;/string 转 char char* zhuanhuan(string ipdata) char *dst = new char255; int i; for(i=0;i =ipdata.length();i+) dsti=ipdatai; dsti = 0; return dst;精品文档4.3设计结果及结果分析在编译通过后,就可以调用该程序保存目录下的可执行文件了,通过命令提示符来操作,具体结果如下图所示:五、基于IP多播的网络会议程序5.1设计步骤1.创建一个SOCK_DGRAM类型的Socket。2.将此socket绑定到本地的一个端口上,为了实现接收服务器端发送的多播数据。3.加入多播组。4.创建接收线程:只负责接收数据5.创建发送线程:只负责发送数据5.2调试过程该程序可以在同一局域网内多台机器上进行测试,只要用的同一接口就能加入多人聊天,5.3调试结果及结果分析。该程序的最终目的是实现多播,就是能同时给多带计算机发送消息,我取消了发送端和接收端的区别,做成了群聊,每个人都可以发送和接受其他人的消息:运行结果如下图所示:六、网络嗅探器实验目的参照附录4 raw socket编程例子,设计一个可以监视网络的状态、数据流动情况以及网络上传输的信息的网络嗅探器实验原理原始套接字是一种不同于SOCK_STREAM和SOCK_DGRAM的套接字,它实现于系统核心。它的创建方式跟TCP/UDP创建方法几乎是一模一样,例如,通过int sockfd;sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);这两句程序你就可以创建一个原始套接字。这种类型套接字的功能与TCP或者UDP类型套接字的功能有很大的不同:TCP/UDP类型的套接字只能够访问传输层以及传输层以上的数据,因为当IP层把数据传递给传输层时,下层的数据包头已经被丢掉了。而原始套接字却可以访问传输层以下的数据,所以使用raw套接字你可以实现上至应用层的数据操作,也可以实现下至链路层的数据操作。比如:通过sock=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)方式创建的rawsocket就能直接读取链路层的数据。1)使用原始套接字时应该注意的问题(参考以及网上的优秀文档)(1):对于UDP/TCP产生的IP数据包,内核不将它传递给任何原始套接字,而只是将这些数据交给对应的UDP/TCP数据处理句柄(所以,如果你想要通过原始套接字来访问TCP/UDP或者其它类型的数据,调用socket函数创建原始套接字第三个参数应该指定为htons(ETH_P_IP),也就是通过直接访问数据链路层来实现。(我们后面的密码窃取器就是基于这种类型的)。(2):对于ICMP和EGP等使用IP数据包承载数据但又在传输层之下的协议类型的IP数据包,内核不管是否已经有注册了的句柄来处理这些数据,都会将这些IP数据包复制一份传递给协议类型匹配的原始套接字。(3):对于不能识别协议类型的数据包,内核进行必要的校验,然后会查看是否有类型匹配的原始套接字负责处理这些数据,如果有的话,就会将这些IP数据包复制一份传递给匹配的原始套接字,否则,内核将会丢弃这个IP数据包,并返回一个ICMP主机不可达的消息给源主机。(4):如果原始套接字bind绑定了一个地址,核心只将目的地址为本机IP地址的数据包传递给原始套接字,如果某个原始套接字没有bind地址,核心就会把收到的所有IP数据包发给这个原始套接字。(5):如果原始套接字调用了connect函数,则核心只将源地址为connect连接的IP地址的IP数据包传递给这个原始套接字。(6):如果原始套接字没有调用bind和connect函数,则核心会将所有协议匹配的IP数据包传递给这个原始套接字。2)编程选项原始套接字是直接使用IP协议的非面向连接的套接字,在这个套接字上可以调用bind和connect函数进行地址绑定。说明如下:(1)bind函数:调用bind函数后,发送数据包的源IP地址将是bind函数指定的地址。如果不调用bind,则内核将以发送接口的主IP地址填充IP头。如果使用setsockopt设置了IP_HDRINCL(headerincluding)选项,就必须手工填充每个要发送的数据包的源IP地址,否则,内核将自动创建IP首部。(2)connetc函数:调用connect函数后,就可以使用write和send函数来发送数据包,而且内核将会用这个绑定的地址填充IP数据包的目的IP地址,否则的话,则应使用sendto或sendmsg函数来发送数据包,并且要在函数参数中指定对方的IP地址。综合以上种种功能和特点,我们可以使用原始套接字来实现很多功能,比如最基本的数据包分析,主机嗅探等。其实也可以使用原始套接字作一个自定义的传输层协议。实验结果七、心得体会通过本次课程设计,我收获了不少东西, 通过编写计算机程序实现、模拟网络的一些功能,使我理解并掌握计算机网络的基本原理及工作过程。对系统调用和应用编程接口基本知识更加熟悉,了解了应用程序和操作系统之间传递控制权的机制,并掌握了套接字的创建和运用,通过socket系统调用实现跨网络通信。 同时提高了我实际编程能力和灵活运用所学知识解决的能力。让我提高了自己调查研究、查阅技术文献、资料、手册以及编写技术文档的能力,理论应用于实践的能力。八、参考文献1.谢希仁,计算机网络(第五版),电子工业出版社,2008。2.百度 3计算网络课程设计指导书。九、附录附录一:聊天程序源代码附录二:Ping程序源代码附录三:IP多播的网络会议程序源代码附录一:服务端代码:.#include #include #include#define MaxSize 50using namespace std;HANDLE hMutex;/发送函数void Send(SOCKET sockClient) char sendBufMaxSize; int byte = 0; while(1) WaitForSingleObject(hMutex, INFINITE);/第一个参数;hHandlein对象句柄。可以指定一系列的对象 第二个参数:定时时间间隔/完成线程间通信 gets(sendBuf); byte= send(sockClient,sendBuf,50,0);/服务器向客户端发送数据 if (byte=0) break; Sleep(1000); ReleaseMutex(hMutex); closesocket(sockClient);/关闭socket,一次通信完毕/接收函数void Rec(SOCKET sockClient) char revBufMaxSize; int byte = 0; while(1) WaitForSingleObject(hMutex, INFINITE); byte= recv(sockClient,revBuf,50,0);/服务器从客户端接受数据 if (byte=0) break; printf(KHD: %sn,revBuf); Sleep(1000); ReleaseMutex(hMutex); closesocket(sockClient);/关闭socket,一次通信完毕int main()WORD wVersionRequested; /使用的WinSock版本WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );/完成对Winsock服务的初始化if ( err != 0 ) return 0;/ 返回值为零的时候是表示成功申请WSAStartupif ( LOBYTE( wsaData.wVersion ) != 1 | HIBYTE( wsaData.wVersion ) != 1 ) WSACleanup( );/中止Windows Sockets在所有线程上的操作return 0;SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);/ 创建socket操作,建立流式套接字,返回套接字号sockSrv/ 第一个参数,指定地址簇(TCP/IP只能是AF_INET,也可写成PF_INET) / 第二个,选择套接字的类型(流式套接字),第三个,特定地址家族相关协议(0为自动)SOCKADDR_IN addrSrv;/声明结构体addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/将IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据addrSrv.sin_family=AF_INET;/sin_family表示地址族,对于IP地址,sin_family成员将一直是AF_INETaddrSrv.sin_port=htons(6000);/指定将要分配给套接字的端口。bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/绑定套接字到一个IP地址和一个端口上/*第一个参数,指定需要绑定的套接字;第二个参数,指定该套接字的本地地址信息,该地址结构会随所用的网络协议的不同而不同第三个参数,指定该网络协议地址的长度*/listen(sockSrv,5); /将套接字设定为监听模式等待连接请求 /第一个参数指定需要设置的套接字,第二个参数为(等待连接队列的最大长度)SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);while(1) SOCKET sockClient=accept(sockSrv,(SOCKADDR*)&addrClient,&len); HANDLE hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Send,(LPVOID)sockClient,0,0);/发送 /*lpThreadAttributes: Pointer; 安全设置 dwStackSize: DWORD; 堆栈大小 lpStartAddress: TFNThreadStartRoutine; 入口函数 lpParameter: Pointer; 函数参数 dwCreationFlags: DWORD; 启动选项 var lpThreadId: DWORD 输出线程 ID*/ if(hThread1!=NULL) CloseHandle(hThread1); HANDLE hThread2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Rec,(LPVOID)sockClient,0,0);/接收 if(hThread2!=NULL) CloseHandle(hThread2); getchar();return 0;客户端代码:#include #include #include #include #define MaxSize 50using namespace std;HANDLE hMutex;void Send(SOCKET sockClient) char sendBufMaxSize; int byte = 0; while(1) WaitForSingleObject(hMutex, INFINITE); gets(sendBuf); byte= send(sockClient,sendBuf,50,0);/服务器从客户端接受数据 if (byte=0) break; Sleep(1000); ReleaseMutex(hMutex); closesocket(sockClient);/关闭socket,一次通信完毕void Rec(SOCKET sockClient) char revBufMaxSize; int byte = 0; while(1) WaitForSingleObject(hMutex, INFINITE); byte= recv(sockClient,revBuf,50,0);/服务器从客户端接受数据 if (byte=0) break; printf(FWQ: %sn,revBuf); Sleep(1000); ReleaseMutex(hMutex); closesocket(sockClient);/关闭socket,一次通信完毕int main() WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); /通过连接两个给定的无符号参数,创建一个无符号16位整形 err = WSAStartup( wVersionRequested, &wsaData );/完成对Winsock服务的初始化 if ( err != 0 ) /判断函数返回值 return 0; if ( LOBYTE( wsaData.wVersion ) != 1 | HIBYTE( wsaData.wVersion ) != 1 )/是取得16进制数最低(最右边)那个字节的内容,取得16进制数最高(最左边)那个字节的内容/用于判断版本是否一致 WSACleanup( );/中止Windows Sockets在所有线程上的操作 return 0; while(1) SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr=inet_addr();/绑定套接字到一个IP地址和一个端口上; addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/建立连接 HANDLE hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Rec,(LPVOID)sockClient,0,0); if(hThread1!=NULL) CloseHandle(hThread1); HANDLE hThread2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Send,(LPVOID)sockClient,0,0); if(hThread2!=NULL) CloseHandle(hThread2); getchar(); WSACleanup();/中止Windows Sockets在所有线程上的操作 return 0;精品文档附录二#include #include #include #include #include #include #include #include using namespace std;/IP报头typedef struct IP_HEADER unsigned char hdr_len:4; /4位头部长度 unsigned char version:4; /4位版本号 unsigned char tos; /8位服务类型 unsigned short total_len; /16位总长度 unsigned short identifier; /16位标识符 unsigned short frag_and_flags; /3位标志加13位片偏移 unsigned char ttl; /8位生存时间 unsigned char protocol; /8位上层协议号 unsigned short checksum; /16位校验和 unsigned long sourceIP; /32位源IP地址 unsigned long destIP; /32位目的IP地址 IP_HEADER;/ICMP报头typedef struct ICMP_HEADER BYTE type; /8位类型字段 BYTE code; /8位代码字段 USHORT cksum; /16位校验和 USHORT id; /16位标识符 USHORT seq; /16位序列号 ICMP_HEADER;/报文解码结构typedef struct DECODE_RESULT USHORT usSeqNo; /序列号 DWORD dwRoundTripTime; /往返时间 in_addr dwIPaddr; /返回报文的IP地址DECODE_RESULT;/计算网际校验和函数USHORT checksum( USHORT *pBuf, int iSize ) unsigned long cksum = 0; while( iSize 1 ) cksum += *pBuf+; iSize -= sizeof(USHORT); if( iSize )/如果 iSize 为正,即为奇数个字节 cksum += *(UCHAR *)pBuf; /则在末尾补上一个字节,使之有偶数个字节 cksum = ( cksum 16 ) + ( cksum&0xffff ); cksum += ( cksum 16 ); return (USHORT)( cksum );/对数据包进行解码BOOL DecodeIcmpResponse(char * pBuf, int iPacketSize, DECODE_RESULT &DecodeResult, BYTE ICMP_ECHO_REPLY, BYTE ICMP_TIMEOUT) /检查数据报大小的合法性 IP_HEADER* pIpHdr = ( IP_HEADER* )pBuf; int iIpHdrLen = pIpHdr-hdr_len * 4; /ip报头的长度是以4字节为单位的 /若数据包大小 小于 IP报头 + ICMP报头,则数据报大小不合法 if ( iPacketSize type = ICMP_ECHO_REPLY ) /ICMP回显应答报文 usID = pIcmpHdr-id; /报文ID usSquNo = pIcmpHdr-seq; /报文序列号 else if( pIcmpHdr-type = ICMP_TIMEOUT )/ICMP超时差错报文 char * pInnerIpHdr = pBuf + iIpHdrLen + sizeof( ICMP_HEADER ); /载荷中的IP头 int iInnerIPHdrLen = ( ( IP_HEADER * )pInnerIpHdr )-hdr_len * 4; /载荷中的IP头长 ICMP_HEADER * pInnerIcmpHdr = ( ICMP_HEADER * )( pInnerIpHdr + iInnerIPHdrLen );/载荷中的ICMP头 usID = pInnerIcmpHdr-id; /报文ID usSquNo = pInnerIcmpHdr-seq; /序列号 else return false; /检查ID和序列号以确定收到期待数据报 if( usID != ( USHORT )GetCurrentProcessId() | usSquNo != DecodeResult.usSeqNo ) return false; /记录IP地址并计算往返时间 DecodeResult.dwIPaddr.s_addr = pIpHdr-sourceIP; DecodeResult.dwRoundTripTime = GetTickCount() - DecodeResult.dwRoundTripTime; /处理正确收到的ICMP数据报 if ( pIcmpHdr-type = ICMP_ECHO_REPLY | pIcmpHdr-type = ICMP_TIMEOUT ) /输出往返时间信息 if(DecodeResult.dwRoundTripTime) cout DecodeResult.dwRoundTripTimemsflush; else cout 1msflush; return true;/获取Ip地址的最后一个字段int getIp(char Address) int count =1; int i, len = strlen(Address); for(i = 0; i len & count 4; i+) if(Addressi = .) count+; int ip = 0; for(; i len; i+) ip = ip * 10 + (Addressi - 0); return ip;/int 转 string 类型string intToString(int v) stringstream s; sv; string str = s.str(); return str;/string 转 char char* zhuanhuan(string ipdata) char *dst = new char255; int i; for(i=0;i =ipdata.length();i+) dsti=ipdatai; dsti = 0; return dst;int main() /初始化Windows sockets网络环境 WSADATA wsa; WSAStartup( MAKEWORD(2,2), &wsa); char IpAddress255; char EndIpAddress255; coutIpAddress; coutEndIpAddress; /得到IP地址 u_long ulDestIP = inet_addr( IpAddress ); u_long ulEndIP=inet_addr( EndIpAddress ); /转换不成功时按域名解析 if( ulDestIP = INADDR_NONE ) hostent * pHostent = gethostbyname( IpAddress ); if( pHostent ) ulDestIP = ( *( in_addr* )pHostent-h_addr).s_addr; else cout输入的IP地址或域名无效!endl; WSACleanup(); return 0; coutTracing roote from IpAddress to EndIpAddress with a maximum of 2 hops.nendl; /得到最后一个字段 int starip=getIp(IpAddress); int endip=getIp(EndIpAddress); for(int i=starip; i=endip; i+) char p15=10.1.13.; string str1(p); string ipdata = str1 +intToString(i); coutzhuanhuan(ipdata)type = ICMP_ECHO_REQUEST; /类型为请求回显 pIcmpHeader-code = 0; /代码字段为0 pIcmpHeader-id = (USHORT)GetCurrentProcessId(); /ID字段为当前进程号 memset( IcmpSendBuf + sizeof( ICMP_HEADER ), E, DEF_ICMP_DATA_SIZE );/数据字段 USHORT usSeqNo = 0; /ICMP报文序列号 int iTTL = 1; /TTL初始值为1 BOOL bReachDestHost = FALSE; /循环退出标志 int iMaxHot = DEF_MAX_HOP; /循环的最大次数 DECODE_RESULT DecodeResult; /传递给报文解码函数的结构化参数 while( !bReachDestHost & iMaxHot- ) /设置IP报头的TTL字段 setsockopt( sockRaw, IPPROTO_IP, IP_TTL, (char *)&iTTL, sizeof(iTTL) ); /coutiTTLcksum = 0; /校验和先置为0 (ICMP_HEADER *)IcmpSendBuf)-seq = htons(usSeqNo+); /填充序列号 (ICMP_HEADER *)IcmpSendBuf)-cksum = checksum( ( USHORT * )

温馨提示

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

评论

0/150

提交评论