多线程ping程序出现“段异常”,求解
多线程ping程序出现“段错误”,求解
本程序主要实现同时测量到多个地址的延时值,用多线程实现。本程序在ipv4和ipv6环境下均适用,但主要目的是在ipv6环境下测时延。以下显示代码是程序的核心部分,但运行有错误,求高手相助!
//initial 初始化
//send 发包
//recv 收包
//proc 处理包,即取包中的数据,计算延时并显示
void *initialsendrecvproc( struct addrinfo *ai )
{//为方便查找错误,本函数进行了简化,去掉了循环
//只发一个ping包,然后接收该ping包的返回包
//最后计算这两个包的时间差,并输出该时间差值
int size;
int nsent;
char recvbuf[BUFSIZE];
char controlbuf[BUFSIZE];
struct msghdr msg;
struct iovec iov;
ssize_t n;
struct timeval tval;
struct proto *pr;
if (ai->ai_family == AF_INET) { //ipv4
pr = &proto_v4;
#ifdef IPV6
} else if (ai->ai_family == AF_INET6) { //ipv6
pr = &proto_v6;
if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr)))
err_quit("cannot ping IPv4-mapped IPv6 address");
#endif
} else
err_quit("unknown address family %d", ai->ai_family);
pr->sasend = ai->ai_addr;
pr->sarecv = Calloc(1, ai->ai_addrlen);
pr->salen = ai->ai_addrlen;
sockfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto); //使用原始套接字
setuid(getuid());
if (pr->finit)
(*pr->finit)( );
nsent = 0;
size = 60 * 1024;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));//设置套接字选项
iov.iov_base = recvbuf;
iov.iov_len = sizeof(recvbuf);
msg.msg_name = pr->sarecv;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = controlbuf;
send_v6(pr, &nsent); //发一个包
msg.msg_namelen = pr->salen;
msg.msg_controllen = sizeof(controlbuf);
n = recvmsg(sockfd, &msg, 0);//收上面刚发的包
Gettimeofday(&tval, NULL);//得到当前时间
proc_v6(recvbuf, n, &msg, &tval, pr);//处理包,计算延时并显示
//标记1 printf(“hj\n”);
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
int i;
struct addrinfo *ai;
char *h;
//ipaddress是一个纯文本文件,为排错方便,文件里只包含两行字符串
//第一行是”www.google.com” 第二行是”www.kame.net”
if ((fp1 = fopen("ipaddress","r")) == NULL)
{
printf("cannot open infile\n");
exit(0);
}
while(!feof(fp1))
{
fscanf(fp1,"%s",host); //host的定义语句为 char host[100]
ai = Host_serv(host, NULL, 0, 0);
h = Sock_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);
memset(&thread, 0, sizeof(thread));
if (( pthread_create(&thread, NULL, initialsendrecvproc(ai), NULL)) != 0)
{
printf("thread %d create fail!\n", i++);
本程序主要实现同时测量到多个地址的延时值,用多线程实现。本程序在ipv4和ipv6环境下均适用,但主要目的是在ipv6环境下测时延。以下显示代码是程序的核心部分,但运行有错误,求高手相助!
//initial 初始化
//send 发包
//recv 收包
//proc 处理包,即取包中的数据,计算延时并显示
void *initialsendrecvproc( struct addrinfo *ai )
{//为方便查找错误,本函数进行了简化,去掉了循环
//只发一个ping包,然后接收该ping包的返回包
//最后计算这两个包的时间差,并输出该时间差值
int size;
int nsent;
char recvbuf[BUFSIZE];
char controlbuf[BUFSIZE];
struct msghdr msg;
struct iovec iov;
ssize_t n;
struct timeval tval;
struct proto *pr;
if (ai->ai_family == AF_INET) { //ipv4
pr = &proto_v4;
#ifdef IPV6
} else if (ai->ai_family == AF_INET6) { //ipv6
pr = &proto_v6;
if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr)))
err_quit("cannot ping IPv4-mapped IPv6 address");
#endif
} else
err_quit("unknown address family %d", ai->ai_family);
pr->sasend = ai->ai_addr;
pr->sarecv = Calloc(1, ai->ai_addrlen);
pr->salen = ai->ai_addrlen;
sockfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto); //使用原始套接字
setuid(getuid());
if (pr->finit)
(*pr->finit)( );
nsent = 0;
size = 60 * 1024;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));//设置套接字选项
iov.iov_base = recvbuf;
iov.iov_len = sizeof(recvbuf);
msg.msg_name = pr->sarecv;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = controlbuf;
send_v6(pr, &nsent); //发一个包
msg.msg_namelen = pr->salen;
msg.msg_controllen = sizeof(controlbuf);
n = recvmsg(sockfd, &msg, 0);//收上面刚发的包
Gettimeofday(&tval, NULL);//得到当前时间
proc_v6(recvbuf, n, &msg, &tval, pr);//处理包,计算延时并显示
//标记1 printf(“hj\n”);
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
int i;
struct addrinfo *ai;
char *h;
//ipaddress是一个纯文本文件,为排错方便,文件里只包含两行字符串
//第一行是”www.google.com” 第二行是”www.kame.net”
if ((fp1 = fopen("ipaddress","r")) == NULL)
{
printf("cannot open infile\n");
exit(0);
}
while(!feof(fp1))
{
fscanf(fp1,"%s",host); //host的定义语句为 char host[100]
ai = Host_serv(host, NULL, 0, 0);
h = Sock_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);
memset(&thread, 0, sizeof(thread));
if (( pthread_create(&thread, NULL, initialsendrecvproc(ai), NULL)) != 0)
{
printf("thread %d create fail!\n", i++);