当前位置: 技术问答>linux和unix
一个进程中运行多个ping,接收出错
来源: 互联网 发布时间:2017-01-16
本文导语: 我在事件链表中定时去向一个目的地址发送ICMP报文,同时在读链表中添加读事件,(其实就是一个ping程序),这时没有错误,但是当我同时运行2个或两个以上的ping程序时,偶尔会出现这样的情况:A地址根本就是断...
我在事件链表中定时去向一个目的地址发送ICMP报文,同时在读链表中添加读事件,(其实就是一个ping程序),这时没有错误,但是当我同时运行2个或两个以上的ping程序时,偶尔会出现这样的情况:A地址根本就是断开的,但B地址可以平通,结果显示A也能收到包。请各位高手指点。
代码如下:
代码如下:
#include
#include "prefix.h"
#include "table.h"
#include "rib.h"
#include
#include
#include "zebra_vty.h"
#include "memory.h"
#include "debug.h"
#include "rt.h"
#define PACKET_SIZE 1024
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
pid_t prid;
extern struct thread_master *master;
struct list *static_route_monitor = NULL;
unsigned short cal_chksum(unsigned short *addr,int len);
void send_packet(int fd);
int recv_packet(void);
int unpack(char *buf,int len);
/*校验和算法*/
unsigned short cal_chksum(unsigned short *addr,int len)
{
int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;
/*把ICMP报头二进制数据以2字节为单位累加起来*/
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
/*若ICMP报头为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节,这个2字节数据的低字节为0,继续累加*/
if( nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
}
/*设置ICMP报头*/
int pack(int pack_no, char *sendpacket)
{
int packsize;
struct icmphdr *icmp;
icmp=(struct icmphdr*)sendpacket;
icmp->type=ICMP_ECHO;
icmp->code=0;
icmp->checksum=0;
icmp->un.echo.sequence=pack_no;
icmp->un.echo.id=prid;
packsize=8+40;
icmp->checksum=cal_chksum( (unsigned short *)icmp,packsize); /*校验算法*/
return packsize;
}
/*剥去ICMP报头*/
int unpack(char *buf,int len)
{
int iphdrlen;
struct iphdr *ip;
struct icmphdr *icmp;
ip=(struct iphdr *)buf;
iphdrlen=ip->ihlthread_rec = thread_add_read(master, recv_monitor_packet, sroute, sroute->sockfd);
}
else
{
close(sroute->sockfd);
sroute->sockfd = 0;
THREAD_OFF(sroute->thread_timeout);
zebra_route_update(sroute, 1);
}
return 0;
}
int send_monitor_packet_timeout(struct thread *t)
{
struct zebra_route_monitor_st *sroute;
sroute = THREAD_ARG(t);
sroute->thread_timeout = NULL;
close(sroute->sockfd);
THREAD_OFF(sroute->thread_rec);
zebra_route_update(sroute, 2);
return 0;
}
int send_monitor_packet(struct thread *t) //开始发送报文
{
int sendfd = -1;
struct zebra_route_monitor_st *sroute;
struct in_addr nexthop_IP;
struct in_addr monitor_addr;
sroute = THREAD_ARG (t);
inet_aton(sroute->route.gate_str,&nexthop_IP);
sroute->thread_send = thread_add_timer(master,send_monitor_packet,sroute,sroute->route.m_interval); //定时发送报文
inet_aton(sroute->route.monitor_addr,&monitor_addr);
sendfd = do_detect(sroute->bind_ifname,monitor_addr,sroute->route.packet_count);
if(sendfd sockfd = sendfd;
if(sroute->thread_rec)
THREAD_OFF(sroute->thread_rec);
sroute->thread_rec = thread_add_read(master, recv_monitor_packet, sroute, sendfd); //读取报文看看是否ping通了
if(sroute->thread_timeout)
THREAD_OFF(sroute->thread_timeout);
sroute->thread_timeout = thread_add_timer(master,send_monitor_packet_timeout,sroute, sroute->route.timeout);
return 0;
}
int zebra_route_test(struct zebra_route_monitor_st *data)
{
struct zebra_route_monitor_st *sroute;
struct zebra_route_monitor_st *monitor = NULL;
...........
...........
monitor = XMALLOC(MTYPE_ROUTE_MONITOR, sizeof(struct zebra_route_monitor_st));
if(!monitor)
return 4;
memset(monitor, 0, sizeof(struct zebra_route_monitor_st));
memcpy(monitor, sroute, sizeof(struct zebra_route_monitor_st));
if(monitor->route.m_interval route.m_interval = ROUTE_TEST_LOOPTIME;
if(monitor->route.timeout route.timeout > monitor->route.m_interval)
monitor->route.timeout = ROUTE_TEST_TIMEOUT;
//if(monitor->route.monitor_IP.s_addr == 0)
//inet_aton(monitor->route.gate_str, &(monitor->route.monitor_IP));
listnode_add(static_route_monitor, monitor); //这个static_route_monitor是一个ping链表,我向其中
//加ping程序,当我只是做一个定期ping时没问题,但
//添加多个定时ping就偶尔会出问题
monitor->thread_send =thread_add_timer(master, send_monitor_packet, monitor, 1); //开始定时发包,
//ping程序开始运行
return 0;
}
|
你在recv_monitor_packet 里面多检查一下来源ip不就可以了么
|
原始套接字是整个系统的,所以发往本机的包将会产生N份副本送往N个原始套接字.
|
你直接看网络编程原始套接字章节第一页就知道为什么了.