linux ping程序设计与实现,linux下ping程序实现

这里使用socket实现ping程序的所有功能。

可以借此了解以下icmp协议的设计细节和注意事项。

支持以下功能:

支持ping域名和ip地址

支持自定义发包个数

支持自定义ttl

支持超时设定

使用方法:

//打印帮助

Linux_ping -h

//参数设定

Linux_ping -c 10 -t 100 -w 100 ip/域名

来介绍下功能关键点:

创建ICMP套接字

//RAW套接字,需要root权限

g_sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);

TTL设定

TTL(Time To Live)

该字段指定IP包被路由器丢弃之前允许通过的最大网段数量

如果设置的ttl过小,那么就就会收不到回包

UINT32 ttl = TTL;

setsockopt(g_sockfd, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl));

域名到IP的转换

//是主机名

if (inet_addr(szHost) == INADDR_NONE)

{

host = gethostbyname(szHost);

if(host==NULL)

{

perror("获取主机名错误");

return -1;

}

//成功的话,ip地址存在host里面

}

字符串到IP的转换

dest_addr.sin_addr.s_addr = inet_addr(szHost);

printf("IP:%s\n", inet_ntoa(g_dest_addr.sin_addr));

网络字节序

网络字节序是大端

X86体系是小端字节序,一般都需要自行转换字节序

以下常用函数用于字节序转换:

//主机序->网络序

htonl()

//网络序->主机序

ntohl()

自定义ICMP报头

//类型

icmp->icmp_type = ICMP_ECHO;

icmp->icmp_code = 0;

//校验码,必须默认置0

icmp->icmp_cksum = 0;

icmp->icmp_seq = pack_no;

icmp->icmp_id=pid;

//头部8个字节

packsize = 8 + g_datalen;

icmp->icmp_cksum=cal_chksum((unsigned short *)icmp, packsize);

使用alarm()设置超时

alarm()主要功能: 设置信号传送闹钟

即用来设置信号SIGALRM在经过参数seconds秒数后发送给目前的进程

果在seconds秒内再次调用了alarm函数则后面定时器的设置将覆盖前面的设置

主要逻辑:

signal(SIGALRM,Statistic);

while(g_nRecv < g_nNeedSend)

{

alarm(g_nWait);

recvfrom(g_sockfd, g_RecvPacket, sizeof(g_RecvPacket), 0, (struct sockaddr *)&g_from,&nfromlen);

}

这里使用了阻塞recvfrom(),如果接收超时会触发我们设置的signal函数

运行结果:

ff0f04a2a616ad0be97c51ee5565040b.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值