计算机网络课程设计指导书_12计算机_网络工程(3)(5)

2018-12-29 23:00

计算机网络 课程设计指导书

remote.sin_family = AF_INET; remote.sin_port = htons(MCASTPORT); remote.sin_addr.s_addr = inet_addr( MCASTADDR ); if(( sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote, sizeof(remote),NULL,NULL,NULL,NULL, JL_BOTH)) == INVALID_SOCKET) { printf(\ closesocket(sock); WSACleanup(); return -1; } //发送多播数据,当用户在控制台输入\时退出。 while(1) { printf(\ scanf(\ if( sendto(sockM,(char*)sendbuf,strlen(sendbuf),0,(struct sockaddr*) &remote,sizeof(remote))==SOCKET_ERROR) { printf(\ closesocket(sockM); closesocket(sock); WSACleanup(); return -1; } if(strcmp(sendbuf,\ Sleep(500); } closesocket(sockM); closesocket(sock); WSACleanup(); return 0; }

//receiver.cpp

#include #include #include #include

#define MCASTADDR \本例使用的多播组地址。

20

计算机网络 课程设计指导书

#define MCASTPORT 5150 //绑定的本地端口号。 #define BUFSIZE 1024 //接收数据缓冲大小。 int main( int argc,char ** argv) { WSADATA wsd; struct sockaddr_in local,remote,from; SOCKET sock,sockM; TCHAR recvbuf[BUFSIZE]; /*struct ip_mreq mcast; // Winsock1.0 */ int len = sizeof( struct sockaddr_in); int ret; //初始化WinSock2.2 if( WSAStartup( MAKEWORD(2,2),&wsd) != 0 ) { printf(\ return -1; } /* 创建一个SOCK_DGRAM类型的SOCKET 其中,WSA_FLAG_MULTIPOINT_C_LEAF表示IP多播在控制面层上属于

\无根\类型; WSA_FLAG_MULTIPOINT_D_LEAF表示IP多播在数据面层上属于\无根\

有关控制面层和 数据面层有关概念请参阅MSDN说明。 */ if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0, WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF| WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { printf(\ WSACleanup(); return -1; } //将sock绑定到本机某端口上。 local.sin_family = AF_INET; local.sin_port = htons(MCASTPORT); local.sin_addr.s_addr = INADDR_ANY; if( bind(sock,(struct sockaddr*)&local,sizeof(local)) == SOCKET_ERROR ) { printf( \ closesocket(sock); WSACleanup(); return -1;

21

计算机网络 课程设计指导书

}

//加入多播组

remote.sin_family = AF_INET;

remote.sin_port = htons(MCASTPORT);

remote.sin_addr.s_addr = inet_addr( MCASTADDR ); /* Winsock1.0 */ /*

mcast.imr_multiaddr.s_addr = inet_addr(MCASTADDR); mcast.imr_interface.s_addr = INADDR_ANY;

if( setsockopt(sockM,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,

sizeof(mcast)) == SOCKET_ERROR) {

printf(\ closesocket(sockM); WSACleanup(); return -1; } */

/* Winsock2.0*/

if(( sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote), NULL,NULL,NULL,NULL, JL_BOTH)) == INVALID_SOCKET) { printf(\ closesocket(sock); WSACleanup(); return -1; }

//接收多播数据,当接收到的数据为\时退出。 while(1) { if(( ret = recvfrom(sock,recvbuf,BUFSIZE,0, (struct sockaddr*)&from,&len)) == SOCKET_ERROR) { printf(\ closesocket(sockM); closesocket(sock); WSACleanup(); return -1; } if( strcmp(recvbuf,\

22

计算机网络 课程设计指导书

else { recvbuf[ret] = '\\0'; printf(\ } }

closesocket(sockM); closesocket(sock); WSACleanup(); return 0;

}

23

计算机网络 课程设计指导书

附录4:raw socket编程例子 1原始套接字工作原理与规则

原始套接字是一种不同于SOCK_STREAM和SOCK_DGRAM的套接字,它实现于系统核心。它的创建方式跟TCP/UDP创建方法几乎是一模一样,例如,通过

int sockfd;

sockfd=socktet(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地址。

综合以上种种功能和特点,我们可以使用原始套接字来实现很多功能,比如最基本的数据包分析,主机嗅探等。其实也可以使用原始套接字作一个自定义的传输层协议。

24


计算机网络课程设计指导书_12计算机_网络工程(3)(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:项目管理学复习题(带答案)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: