免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1872 | 回复: 7
打印 上一主题 下一主题

程序问题,ping! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-09 14:26 |只看该作者 |倒序浏览
static void*
rcv_msg(void *ptr)
{
    int sd,ret;
    struct pong_msg_st rmsg;
    time_t time2;
    struct sigaction sa,osa;

    pthread_detach(pthread_self());
    sa.sa_sigaction=int_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART|SA_SIGINFO;

    sigaction(SIGINT,&sa,&osa);
    
    sd=(int)ptr;
    while(1) {
        ret=recvfrom(sd, &rmsg, sizeof(rmsg), 0, NULL, NULL);
        gettimeofday(&rcvtime,NULL);
        if (ret==-1) {
            if (errno == EAGAIN) {
                puts("Timed out.");
            } else {
                perror("sendto()");
                exit(1);
            }
        } else {
            ++rcvpacket;
            printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms\n",sizeof(rmsg), strip,rmsg.icmphdr.un.echo.sequence,rmsg.iphdr.ttl,(float)((rcvtime.tv_sec - sndtime.tv_sec)*1000 + (rcvtime.tv_usec - sndtime.tv_usec)) * (0.001));
        }
    }
    pthread_exit(NULL);

}

这是收包程序

论坛徽章:
0
2 [报告]
发表于 2008-11-09 14:27 |只看该作者
int sd, i, ret;
    struct addrinfo hint,*res,*cur;
    char ipstr[IP4STRSIZE];
    socklen_t hisend_len;
    struct ping_msg_st msg;
    struct pong_msg_st rmsg;
    struct timeval to;
    struct timespec req,rem;

&nbsp;&nbsp;&nbsp;&nbsp;if (argc<2) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Usage: %s IP or Domain\n", argv[0]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;savedomain=strdup(argv[1]);
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_flags = 0;
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_family = AF_INET;
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_socktype = SOCK_RAW;
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_protocol = IPPROTO_ICMP;
&nbsp;&nbsp;&nbsp;&nbsp;ret=getaddrinfo(argv[1], NULL, &hint, &res);
&nbsp;&nbsp;&nbsp;&nbsp;if (ret) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;inet_ntop(res->ai_family, &((struct sockaddr_in*)(res->ai_addr))->sin_addr, ipstr, IP4STRSIZE);

&nbsp;&nbsp;&nbsp;&nbsp;sd=socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);//自己定义ICMP报头信息;

&nbsp;&nbsp;&nbsp;&nbsp;if (sd==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("socket()");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;to.tv_sec = TIMEOUT;
&nbsp;&nbsp;&nbsp;&nbsp;to.tv_usec = 0;
&nbsp;&nbsp;&nbsp;&nbsp;ret=setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));//设置接受包延迟,3秒没收到则提示没连接;

&nbsp;&nbsp;&nbsp;&nbsp;if (ret==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("setsockopt(SO_RCVTIMEO,)");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.type = ICMP_ECHO;//Echo Request;

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.code = 0;
&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.checksum = 0;//要先给校验和设置为0,然后在给校验和设置值;

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.un.echo.id = htons(getpid());//直接用pid设置id号;

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.un.echo.sequence = 0;//序列从0开始;

&nbsp;&nbsp;&nbsp;&nbsp;for (i=0;i<DATASIZE;++i) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.data[i] = '0'+i;//随便往data里添加任意数据;

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.checksum = csum(&msg, sizeof(msg));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;strip=strdup(ipstr);
&nbsp;&nbsp;&nbsp;&nbsp;ret=pthread_create(&tid,NULL,rcv_msg,(void *)sd);
&nbsp;&nbsp;&nbsp;&nbsp;if (ret) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"pthread_create():%s\n",strerror(ret));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;ret=pthread_create(&tid2,NULL,ctl_list,NULL);
&nbsp;&nbsp;&nbsp;&nbsp;if (ret) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"pthread_create():%s\n",strerror(ret));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

fprintf(stderr,"PING %s (%s) %d(%d) bytes of data.\n",argv[1],ipstr,sizeof(msg.data),sizeof(msg));
&nbsp;&nbsp;&nbsp;&nbsp;req.tv_sec=1;
&nbsp;&nbsp;&nbsp;&nbsp;req.tv_nsec=0;
&nbsp;&nbsp;&nbsp;&nbsp;rem.tv_sec=1;
&nbsp;&nbsp;&nbsp;&nbsp;rem.tv_nsec=0;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&sndtime,NULL);
&nbsp;&nbsp;&nbsp;&nbsp;while (1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret=sendto(sd, &msg, sizeof(msg), 0, res->ai_addr,res->ai_addrlen);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ret==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("sendto()");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.un.echo.sequence++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;packet = msg.hdr.un.echo.sequence;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nanosleep(&req,&rem);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;freeaddrinfo(res);
&nbsp;&nbsp;&nbsp;&nbsp;close(sd);

&nbsp;&nbsp;&nbsp;&nbsp;exit(0);


这是发包程序,为什么每次只是收到第一次发包返回的数据,以后发的包就收不到对方IP返回的包了?

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
3 [报告]
发表于 2008-11-09 16:05 |只看该作者

回复 #2 hightallyht 的帖子

能否贴完整的代码?

论坛徽章:
0
4 [报告]
发表于 2008-11-09 18:22 |只看该作者
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>

#include "checksum.h"

#define DATASIZE 56
#define IP4STRSIZE 16
#define TIMEOUT 3

static pthread_t tid,tid2;
static char *strip=NULL;
static struct timeval sndtime,rcvtime,starttime,endtime;
static char *savedomain=NULL;
static int packet=0;
static int rcvpacket=0;
static int lostpacket=0;
static float avg=0;
static float max=0;
static float min=100;
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t snd_mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct ping_msg_st {
&nbsp;&nbsp;&nbsp;&nbsp;struct icmphdr hdr;
&nbsp;&nbsp;&nbsp;&nbsp;char data[DATASIZE];
};

struct pong_msg_st {
&nbsp;&nbsp;&nbsp;&nbsp;struct iphdr iphdr;
&nbsp;&nbsp;&nbsp;&nbsp;struct icmphdr icmphdr;
&nbsp;&nbsp;&nbsp;&nbsp;char data[DATASIZE];
};

static void
int_handler(int s,siginfo_t *infop , void *ptr)
{
fprintf(stderr,"\n--- %s ping statistics ---\n",savedomain);
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&endtime,NULL);
fprintf(stderr,"%d packets transmitted, %d received, %d packet loss, time %.0fms\n",packet,rcvpacket,lostpacket,(float)((endtime.tv_sec - starttime.tv_sec)*1000 + (endtime.tv_usec - starttime.tv_usec)) * (0.001));
&nbsp;&nbsp;&nbsp;&nbsp;if(rcvpacket) {
fprintf(stderr,"rtt min/avg/max = %.3f/%.3f/%.3f ms\n",min,avg/rcvpacket,max);
}
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
}

static void*
rcv_msg(void *ptr)
{
&nbsp;&nbsp;&nbsp;&nbsp;int sd,ret;
&nbsp;&nbsp;&nbsp;&nbsp;struct pong_msg_st rmsg;
&nbsp;&nbsp;&nbsp;&nbsp;time_t time2;
&nbsp;&nbsp;&nbsp;&nbsp;struct sigaction sa,osa;
&nbsp;&nbsp;&nbsp;&nbsp;float cursave=0;

&nbsp;&nbsp;&nbsp;&nbsp;pthread_detach(pthread_self());
&nbsp;&nbsp;&nbsp;&nbsp;sa.sa_sigaction=int_handler;
&nbsp;&nbsp;&nbsp;&nbsp;sigemptyset(&sa.sa_mask);
&nbsp;&nbsp;&nbsp;&nbsp;sa.sa_flags = SA_RESTART|SA_SIGINFO;

&nbsp;&nbsp;&nbsp;&nbsp;sigaction(SIGINT,&sa,&osa);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;sd=(int)ptr;
&nbsp;&nbsp;&nbsp;&nbsp;while(1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_lock(&mut);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_cond_wait(&cond,&mut);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret=recvfrom(sd, &rmsg, sizeof(rmsg), 0, NULL, NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&rcvtime,NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ret==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (errno == EAGAIN) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++lostpacket;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts("Timed out.");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("sendto()");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++rcvpacket;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cursave = (float)((rcvtime.tv_sec - sndtime.tv_sec)*1000 + (rcvtime.tv_usec - sndtime.tv_usec)) * (0.001);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(min > cursave) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min = cursave;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (max < cursave) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max = cursave;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;avg += cursave;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(strcmp(savedomain,strip) == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms\n",sizeof(rmsg), strip,rmsg.icmphdr.un.echo.sequence,rmsg.iphdr.ttl,cursave);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d bytes from %s (%s): icmp_seq=%d ttl=%d time=%.3f ms\n",sizeof(rmsg),savedomain, strip,rmsg.icmphdr.un.echo.sequence,rmsg.iphdr.ttl,cursave);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_unlock(&mut);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);

}

static void*
ctl_list(void *ptr)
{
&nbsp;&nbsp;&nbsp;&nbsp;int i;

&nbsp;&nbsp;&nbsp;&nbsp;pthread_detach(pthread_self());

&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
}

论坛徽章:
0
5 [报告]
发表于 2008-11-09 18:23 |只看该作者
int
main(int argc, char **argv)
{
&nbsp;&nbsp;&nbsp;&nbsp;int sd, i, ret;
&nbsp;&nbsp;&nbsp;&nbsp;struct addrinfo hint,*res,*cur;
&nbsp;&nbsp;&nbsp;&nbsp;char ipstr[IP4STRSIZE];
&nbsp;&nbsp;&nbsp;&nbsp;socklen_t hisend_len;
&nbsp;&nbsp;&nbsp;&nbsp;struct ping_msg_st msg;
&nbsp;&nbsp;&nbsp;&nbsp;struct pong_msg_st rmsg;
&nbsp;&nbsp;&nbsp;&nbsp;struct timeval to;
&nbsp;&nbsp;&nbsp;&nbsp;struct timespec req,rem;

&nbsp;&nbsp;&nbsp;&nbsp;if (argc<2) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "Usage: %s IP or Domain\n", argv[0]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;savedomain=strdup(argv[1]);
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_flags = 0;
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_family = AF_INET;
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_socktype = SOCK_RAW;
&nbsp;&nbsp;&nbsp;&nbsp;hint.ai_protocol = IPPROTO_ICMP;
&nbsp;&nbsp;&nbsp;&nbsp;ret=getaddrinfo(argv[1], NULL, &hint, &res);
&nbsp;&nbsp;&nbsp;&nbsp;if (ret) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;inet_ntop(res->ai_family, &((struct sockaddr_in*)(res->ai_addr))->sin_addr, ipstr, IP4STRSIZE);

&nbsp;&nbsp;&nbsp;&nbsp;sd=socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);//自己定义ICMP报头信息;

&nbsp;&nbsp;&nbsp;&nbsp;if (sd==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("socket()");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;to.tv_sec = TIMEOUT;
&nbsp;&nbsp;&nbsp;&nbsp;to.tv_usec = 0;
&nbsp;&nbsp;&nbsp;&nbsp;ret=setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));//设置接受包延迟,3秒没收到则提示没连接;

&nbsp;&nbsp;&nbsp;&nbsp;if (ret==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("setsockopt(SO_RCVTIMEO,)");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.type = ICMP_ECHO;//Echo Request;

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.code = 0;
&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.checksum = 0;//要先给校验和设置为0,然后在给校验和设置值;

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.un.echo.id = htons(getpid());//直接用pid设置id号;

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.un.echo.sequence = 0;//序列从0开始;

&nbsp;&nbsp;&nbsp;&nbsp;for (i=0;i<DATASIZE;++i) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.data[i] = '0'+i;//随便往data里添加任意数据;

&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.checksum = csum(&msg, sizeof(msg));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;strip=strdup(ipstr);
&nbsp;&nbsp;&nbsp;&nbsp;ret=pthread_create(&tid,NULL,rcv_msg,(void *)sd);
&nbsp;&nbsp;&nbsp;&nbsp;if (ret) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"pthread_create():%s\n",strerror(ret));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;ret=pthread_create(&tid2,NULL,ctl_list,NULL);
&nbsp;&nbsp;&nbsp;&nbsp;if (ret) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,"pthread_create():%s\n",strerror(ret));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

fprintf(stderr,"PING %s (%s) %d(%d) bytes of data.\n",argv[1],ipstr,sizeof(msg.data),sizeof(msg));
&nbsp;&nbsp;&nbsp;&nbsp;req.tv_sec=1;
&nbsp;&nbsp;&nbsp;&nbsp;req.tv_nsec=0;
&nbsp;&nbsp;&nbsp;&nbsp;rem.tv_sec=1;
&nbsp;&nbsp;&nbsp;&nbsp;rem.tv_nsec=0;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&starttime,NULL);
&nbsp;&nbsp;&nbsp;&nbsp;while (1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&sndtime,NULL);
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_lock(&snd_mut);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret=sendto(sd, &msg, sizeof(msg), 0, res->ai_addr,res->ai_addrlen);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_cond_signal(&cond);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ret==-1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("sendto()");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.hdr.un.echo.sequence++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;packet = msg.hdr.un.echo.sequence;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nanosleep(&req,&rem);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;freeaddrinfo(res);
&nbsp;&nbsp;&nbsp;&nbsp;close(sd);

&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
}

论坛徽章:
0
6 [报告]
发表于 2008-11-09 19:36 |只看该作者
参考此文:
http://linux.chinaunix.net/bbs/v ... p;extra=&page=1
代码太多,没心思看了:wink:

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
7 [报告]
发表于 2008-11-10 00:11 |只看该作者
加了几个头文件,主要问题是后面icmp包的没有计算checksum,sequence应该转为network byte order,Linux的IP和ICMP包头都是network order,所以16bit和32bit的整数字段在接收和发送都要转byte order,附上简单修改的代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>

#define DATASIZE 56
#define IP4STRSIZE 16
#define TIMEOUT 3

static pthread_t tid;
static char *strip=NULL;
static struct timeval sndtime,rcvtime,starttime,endtime;
static char *savedomain=NULL;
static int packet=0;
static int rcvpacket=0;
static int lostpacket=0;
static float avg=0;
static float max=0;
static float min=100;
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

struct ping_msg_st {
    struct icmphdr hdr;
    char data[DATASIZE];
};

struct pong_msg_st {
    struct iphdr iphdr;
    struct icmphdr icmphdr;
    char data[DATASIZE];
};

uint16_t
in_cksum (uint16_t * addr, int len)
{
    int     nleft = len;
    uint32_t sum = 0;
    uint16_t *w = addr;
    uint16_t answer = 0;

    /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
     * sequential 16 bit words to it, and at the end, fold back all the
     * carry bits from the top 16 bits into the lower 16 bits.
     */

    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }
        /* mop up an odd byte, if necessary */
    if (nleft == 1) {
        * (unsigned char *) (&answer) = * (unsigned char *) w;
        sum += answer;
    }

        /* add back carry outs from top 16 bits to low 16 bits */
    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
    sum += (sum >> 16);     /* add carry */
    answer = ~sum;     /* truncate to 16 bits */
    return (answer);
}


static void
int_handler(int s,siginfo_t *infop , void *ptr)
{
    fprintf(stderr,"\n--- %s ping statistics ---\n",savedomain);
    gettimeofday(&endtime,NULL);
    fprintf(stderr,"%d packets transmitted, %d received, %d packet loss, time %.0fms\n",packet,rcvpacket,lostpacket,(float)((endtime.tv_sec - starttime.tv_sec)*1000 + (endtime.tv_usec - starttime.tv_usec)) * (0.001));
    if(rcvpacket) {
        fprintf(stderr,"rtt min/avg/max = %.3f/%.3f/%.3f ms\n",min,avg/rcvpacket,max);
    }
    exit(1);
}

static void*
rcv_msg(void *ptr)
{
    int sd,ret;
    struct pong_msg_st rmsg;
    struct sigaction sa,osa;
    float cursave=0;

    pthread_detach(pthread_self());
    sa.sa_sigaction=int_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART|SA_SIGINFO;

    sigaction(SIGINT,&sa,&osa);
   
    sd=(int)ptr;
    while(1) {
        pthread_mutex_lock(&mut);
        pthread_cond_wait(&cond,&mut);
        ret=recvfrom(sd, &rmsg, sizeof(rmsg), 0, NULL, NULL);
        gettimeofday(&rcvtime,NULL);
        if (ret==-1) {
            if (errno == EAGAIN) {
                ++lostpacket;
                puts("Timed out.");
            } else {
                perror("sendto()");
                exit(1);
            }
        } else {
            ++rcvpacket;
            cursave = (float)((rcvtime.tv_sec - sndtime.tv_sec)*1000 + (rcvtime.tv_usec - sndtime.tv_usec)) * (0.001);
            if(min > cursave) {
                min = cursave;
            }
            if (max < cursave) {
                max = cursave;
            }
            avg += cursave;
            if(strcmp(savedomain,strip) == 0) {
                printf("%d bytes from %s: icmp_seq=%d ttl=%d time=%.3f ms\n",sizeof(rmsg), strip, ntohs(rmsg.icmphdr.un.echo.sequence),rmsg.iphdr.ttl,cursave);
            }else {
                printf("%d bytes from %s (%s): icmp_seq=%d ttl=%d time=%.3f ms\n",sizeof(rmsg),savedomain, strip, ntohs(rmsg.icmphdr.un.echo.sequence), rmsg.iphdr.ttl,cursave);
            }
        }
        pthread_mutex_unlock(&mut);
    }
    pthread_exit(NULL);

}


论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
8 [报告]
发表于 2008-11-10 00:12 |只看该作者
int
main(int argc, char **argv)
{
    int sd, i, ret;
    struct addrinfo hint,*res;
    char ipstr[IP4STRSIZE];
    struct ping_msg_st msg;
    struct timeval to;
    struct timespec req,rem;
    short seq = 0;

    if (argc<2) {
        fprintf(stderr, "Usage: %s IP or Domain\n", argv[0]);
        exit(1);
    }
   
    savedomain=strdup(argv[1]);
    hint.ai_flags = 0;
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_RAW;
    hint.ai_protocol = IPPROTO_ICMP;
    ret=getaddrinfo(argv[1], NULL, &hint, &res);
    if (ret) {
        fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ret));
        exit(1);
    }

    inet_ntop(res->ai_family, &((struct sockaddr_in*)(res->ai_addr))->sin_addr, ipstr, IP4STRSIZE);

    sd=socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);//自己定义ICMP报头信息;



    if (sd==-1) {
        perror("socket()");
        exit(1);
    }

    to.tv_sec = TIMEOUT;
    to.tv_usec = 0;
    ret=setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));//设置接受包延迟,3秒没收到则提示没连接;


    if (ret==-1) {
        perror("setsockopt(SO_RCVTIMEO,)");
        exit(1);
    }

    msg.hdr.type = ICMP_ECHO;//Echo Request;


    msg.hdr.code = 0;
    msg.hdr.checksum = 0;//要先给校验和设置为0,然后在给校验和设置值;


    msg.hdr.un.echo.id = htons((uint16_t)getpid());//直接用pid设置id号;


    msg.hdr.un.echo.sequence = seq;//序列从0开始;


    for (i=0;i<DATASIZE;++i) {
        msg.data[i] = '0'+i;//随便往data里添加任意数据;


    }
    msg.hdr.checksum = in_cksum ((uint16_t*)&msg, sizeof(msg));
   
    strip=strdup(ipstr);
    ret=pthread_create(&tid,NULL,rcv_msg,(void *)sd);
    if (ret) {
        fprintf(stderr,"pthread_create():%s\n",strerror(ret));
        exit(1);
    }

    fprintf(stderr,"PING %s (%s) %d(%d) bytes of data.\n",argv[1],ipstr,sizeof(msg.data),sizeof(msg));
    req.tv_sec=1;
    req.tv_nsec=0;
    rem.tv_sec=1;
    rem.tv_nsec=0;
   
    gettimeofday(&starttime,NULL);
    while (1) {
        gettimeofday(&sndtime,NULL);

        ret=sendto(sd, &msg, sizeof(msg), 0, res->ai_addr,res->ai_addrlen);
        pthread_cond_signal(&cond);
        if (ret==-1) {
            perror("sendto()");
            exit(1);
        }
        seq++;
        msg.hdr.un.echo.sequence = htons(seq);
          msg.hdr.checksum = 0;
        msg.hdr.checksum = in_cksum ((uint16_t*)&msg, sizeof(msg));
        packet = seq;
        nanosleep(&req,&rem);
    }

    freeaddrinfo(res);
    close(sd);

    exit(0);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP