您的位置:首页 > 理论基础 > 计算机网络

网络编程- ping程序简单实现

2017-10-19 22:59 555 查看
   ping程序:ip 发送一个icmp回射请求,该节点以一个icmp回射应答。ipv4,ipv6点格式:

 0                7 8          15 16               31 

  typecode校验和
表示符表示符序列号
datadatadata
   以  ipv 4-- struct icmp 结构体中 icmp_id    ,icmp_type, icmp_code,icmp_seq,等;





表示符一般会设置为-----    pid



#include
"ping.h"
 /*
 ipv4-icmp 发送数据函数
 */
 void
send_v4(void)
 {
 int len;
 struct icmp*icmp;
 icmp=(struct icmp *)sendbuf;
 icmp->icmp_type=ICMP_ECHO;
 icmp->icmp_code=0;
 icmp->icmp_id=pid;
 icmp->icmp_seq=nsent++;
 memset(icmp->icmp_data,0x5a,datalen);//初始化
 gettimeofday((structtimeval *)icmp->icmp_data,NULL);
 len=8+datalen;
 icmp->icmp_cksum=in_cksum((uint16_t *)icmp,len);
 sendto(sockfd,sendbuf,len,0,pr->sasend,pr->salen);
 }
  
其实主要是icmpv6:

void
send_v6(void)
 {
 #ifdef IPV6
 int len;
 struct icmp6_hdr * icmp6;
 icmp6=(strcut icmp6_hdr*)sendbuf;
 icmp6->icmp6_code=0;
 icmp6->icmp6_type=ICMP6_ECHO_REQUEST;
 icmp6->icmp6_id=pid;
 icmp6->icmp6_seq=nsent++;
 memset((icmp6+1),0x5a,datalen);
 gettimeofday((structtimeval*)(icmp6+1),NULL);
 len=8+datalen;
 sendto(sockfd,sendbuf,len,0,pr->sasend,pr->salen);
  
 #endif
 }
mian.c

#include "ping.h"
//赋值ipv4 ipv6
struct proto proto_v4={proc_v4,send_v4,NULL,NULL,0,IPPROTO_ICMP};
#ifdef IPV6
struct proto proto_v6={proc_v6,send_v6,NULL,NULL,0,IPPROTO_ICMPV6};
#endif
int datalen=56;
//icmp的大小
int main(int argc, char *argv[])
{
int c;
struct addrinfo *ai;
char *h;
opterr=0;
while((c=getopt(argc,argv,"v"))!=1)
{
switch(c)
{
case 'v':
verbose++;
break;
case '?':
err_quit("error parament !");
}
}
if(optind!=argc-1)
err_quit("usage : ping [-v] ");
host=argv[argc-1];
pid=getpid() & 0xffff;
ai=host_serv(host,NULL,0,0);
h=inet_ntop_host(ai->ai_addr,ai->ai_addrlen);
printf("PING %s (%s):%d data bytes\n",ai->ai_canonname?ai->ai_canonname:h,h,datalen);
if(ai->ai_family==AF_INET)
{
pr=&proto_v4;

#ifdef IPV6
}else if(ai->ai_family==AF_INET6)
{
pr=&proto_v6;
if(IN6_IS_ADDR_V4MAPPED( &(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr )))
err_quit("error : IPV6");
#endif
}
else
err_quit("nothing i know!");
pr->sasend=ai->ai_addr;
pr->sarecv=calloc(1,ai->ai_addrlen);
pr->salen=ai->ai_addrlen;
readloop();
return 0;
}


具体的icmp的原理过程,我认为参考一下tcp/ip [RFC0792][ RFC443],自己写着玩的一个烂代码,同时也是来源unix网络编程数据。自己好low才玩github没有多久,代码地址:
https://github.com/xiaozw1994/library-libs.git   这只是参考而已;

2、分享一个gcc编译多文件的方法:

   1、gcc    -o test.o  main.c test.c    //一般两个文件没有问题,具体意思大家都知道哈

   2、对于多文件变异是gcc 多个文件会报错:not support mutil-file ,大概是这个意思哈:此时要用一下命令:

   gcc   -shared  file.c -o file.o

   gcc  main.c -lfile.o -L path//路径要是绝对地址

3、如果文件多是还可以引入make命令,make -f make.debug 等,linux下的make 来进行;

4、当然也可以用写一个编译的脚本shell python,其实用C语言的 execl 写一个编译的命令也是可以的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: