RAW协议网络编程(完整程序和注释).doc_第1页
RAW协议网络编程(完整程序和注释).doc_第2页
RAW协议网络编程(完整程序和注释).doc_第3页
RAW协议网络编程(完整程序和注释).doc_第4页
全文预览已结束

下载本文档

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

文档简介

又用了一天,这次写好了,程序依然使用服务器/客户机模式,因此分为服务器程序部分和客户机部分,另外上次写的是面向连接的TCP协议模式,这次我换了一个尝试,使用面向非连接的UDP模式,程序和详细注释如下服务器程序 serve.c 用于发送数据,由于面向非连接,所以它只管发送,发送完了就结束,收没收到它不管#include#include#include#include#include#include#include#include#include 头文件#define MYPORT 4950 端口号int main(int argc,char *argv) 主程序 两个参数 分别为 目标的ip地址,发送的数据int sockfd;struct hostent *he;struct sockaddr_in their_addr;int numbytes;if(argc != 3) 检查参数是否正确,如果输入参数不对,也就别继续了 fprintf(stderr,usage:client hostname messagen);exit(1); printf(0n);if(he=gethostbyname(argv1)=NULL) 这里用到了gethostbyname函数,返回一个指向填充好的数据结构hostent的指针,下面在给附地址值时候会用到这个指针 herror(gethostbyname);exit(1); printf(1n);下面开始调用socket来获得套接口if(sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_UDP)=-1)注意这里的参数 分别代表 支持ipv4协议 raw的原始套接口 protocol选项为IPPROTO_UDP类型,这个很重要,内核根据这个参数包装数据的ip头 perror(socket); exit(1); printf(2n);获得了套接口后开始初始化their_addr.sin_family=AF_INET;their_addr.sin_port=htons(MYPORT);their_addr.sin_addr=*(struct in_addr *)he-h_addr);bzero(&(their_addr.sin_zero), 8);printf(3n);printf(%sn,argv2);由于是面向无连接的通信,有了套接口后就直接发送,目标的ip和发送数据现在都已经知道了numbytes=sendto(sockfd,argv2,strlen(argv2),0,(struct sockaddr *)&their_addr,sizeof(struct sockaddr); printf(4n);输出发送情况printf(sent %d bytes to %sn,numbytes,inet_ntoa(their_addr.sin_addr);close(sockfd);return 0;以上就是发送的程序,这里由于没有设置ip_HDRINCL选项,所以内核负责填充ip头并完成校验和的计算,发送程序只负责传输待发送的数据就好,如果你想自己构造ip头的话那就得设置ip_HDRINCL了,将其flag项置1下面是接收端client.c程序,同样必须采用原始套接字接口内核才会把收到的RAW数据传递给你这个接口#include #include #include #include #include #include #include #include 头文件#define MYPORT 4950 端口号#define maxbuflen 100 最大接受数据下面是主程序main()int sockfd;struct sockaddr_in my_addr;struct sockaddr_in their_addr;int addr_len,numbytes;char bufmaxbuflen; 前面声明一些结构体,这个在之前的编程中也有,一样的开始建立RAW套接口,这里的protocol选项必须与之前的一致,不然那边包装好的数据与这个接口就不符合了if (sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_UDP)=-1) perror(socket); exit(1); printf(1n);my_addr.sin_family=AF_INET;my_addr.sin_port=htons(MYPORT);my_addr.sin_addr.s_addr=INADDR_ANY;bzero(&(my_addr.sin_zero),8);下面是绑定,其实我试过,帮不绑定效果都一样if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr)=-1) perror(bind); exit(1); printf(2n);下面是recvfrom调用,它负责接收服务器传过来的数据addr_len=sizeof(struct sockaddr);if(numbytes=recvfrom(sockfd,buf,maxbuflen,0,(struct sockaddr *)&their_addr,&addr_len)=-1) perror(recvfrom); exit(1); 下面就是接收完成后输出的信息printf(3n);printf(got packet from %sn,inet_ntoa(their_addr.sin_addr);bufnumbytes=0;printf(packet contains :n);int i;这里得好好写一下,为了这个小地方,我从吃晚饭到现在一直在搞,一开始想作为一个整个字符串输出buf,怎么也不显示,之前一切都正常,所以我不得不一步一步检查哪里错了,程序里会有一些printf(“1n”),那是我设置的观察点,这里也就懒得逐一删除了,不影响数据传输的,最后我判定数据肯定已经由服务器传过来了,内核也肯定给了这个套接口了,为什么还是不显示呢,我最后用了个笨方法,我逐位显示字符,不行,那我看看你的ASC码值是多少,这下子知道了,buf的前20个字节是ip头,还有地址信息啥的,前面我不记得了,但是最后的127 0 0 1 127 0 0 1我记得很清楚,然后接下来的才是数据位,所以我显示数据是从第20个数据开始显示,一直到最后 for(i=20;inumbytes;i+)printf( %c,bufi);printf(n);close(sockfd);运行结果:分别编译这两个源文件,然后得先运行接受的客户程序,不然你要先发送,它发完了就完了,不管你接不接受也不跟你连接,这数据就没了,接收程序在recvfrom没有收到数据的时候是卡在那里的,就是阻塞,由于RAW原始套接口只有超级用户才有权限使用,所以必须使用sudo获得拆哦及用户权限,键入以下命令编译gcc o serve serve.cgcc o client client.c运行sudo ./client 注意得先运行客户机的接收程序sudo ./serve 127.0.0.1 lanlan运行结果服务器端输出 sent 6 bytes to 127.0.0.1客户端输出 got packet from 127.0.0.1(由于是在一台机器上开两个窗口,所以客户机与服务器的ip地址是一样的) packet contains: l a n l a n(当然程序里我设置的那些

温馨提示

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

评论

0/150

提交评论