日期:2014-05-16  浏览次数:20831 次

移植问题
在32位上边运行的一点问题也没有,但是移植到64位上边时,问题就来了。

下边是编译时出现的警告,运行时段错误。

源代码也附上。

在源代码中出错的位置也在代码中标记了。

大家指点一下。
C/C++ code


zw@debian:~$ gcc getip.c 
getip.c: In function ‘getaddrbyname’:
getip.c:53: warning: cast to pointer from integer of different size
zw@debian:~$ ./a.out 
段错误






C/C++ code

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/stat.h>

struct ifconf ifc;
char netcard[1024]={0};
char localIP[64]={0};

int getipaddr(){
    int sockfd,len;
    char *ptr;
    struct sockaddr_in *sockaddr_ptr;

    len=sizeof(struct sockaddr);

    sockfd=socket(AF_INET,SOCK_DGRAM,0);

    bzero(netcard,sizeof(netcard));
/*    ifc_len:表示用来存放所有接口信息的缓冲区长度
    ifc_buf:表示存放接口信息的缓冲区
    所以我们需要在程序开始时对ifconf的ifc_led和ifc_buf进行初始化*/
    ifc.ifc_len=1024;
    ifc.ifc_ifcu.ifcu_buf=netcard;

//1. 先通过ioctl获得本地所有接口的信息,并保存在ifconf中
    if(ioctl(sockfd,SIOCGIFCONF,&ifc)<0){
        close(sockfd);
        return 0;
    }
    close(sockfd);
    return 1;
}
int getaddrbyname(const char *name,char *netip){
    int sockfd,len=0;
    char *ptr=NULL;
    struct ifreq *ifrp;
    struct sockaddr_in *sockaddr_ptr;

    if(!getipaddr())
        return 0;

//2. 再从ifconf中取出每一个ifreq中表示ip地址的信息
    for(ptr=netcard;ptr<(netcard+ifc.ifc_len);){
        ifrp=(struct ifreq *)ptr;
        sockaddr_ptr=(struct sockaddr_in *)&ifrp->ifr_ifru.ifru_addr;
        if(strcmp(name,ifrp->ifr_ifrn.ifrn_name)==0){
            memcpy(netip,(char *)inet_ntoa(sockaddr_ptr->sin_addr),32);//53行 :error
            printf("gwip:%s\n",netip);
            return 1;
        }
        ptr+=sizeof(struct ifreq);
    }
    return 0;
}
int main(){
    getaddrbyname("eth0",localIP);
    printf("localIP=%s\n",localIP);
}



------解决方案--------------------
C/C++ code
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/stat.h>

struct ifconf ifc;
char netcard[1024]={0};
char localIP[INET6_ADDRSTRLEN]={0};

int getipaddr(){
    int sockfd,len;
    len=sizeof(struct sockaddr);
    sockfd=socket(AF_INET,SOCK_DGRAM,0);
    bzero(netcard,sizeof(netcard));
    ifc.ifc_len=1024;
    ifc.ifc_ifcu.ifcu_buf=netcard;
    if(ioctl(sockfd,SIOCGIFCONF,&ifc)<0){
        close(sockfd);
        return 0;
    }
    close(sockfd);
    return 1;
}
int getaddrbyname(const char *name,char *netip){
    int sockfd,len=0;
    char *ptr=NULL;
    struct ifreq *ifrp;
    struct sockaddr *sockaddr_ptr; //mark
    if(!getipaddr())
        return 0;
    for(ptr=netcard;ptr<(netcard+ifc.ifc_len);){
        ifrp=(struct ifreq *)ptr;
        sockaddr_ptr=(struct sockaddr*)&ifrp->ifr_ifru.ifru_addr; //mark
        if(strcmp(name,ifrp->ifr_ifrn.ifrn_name)==0){
                        sa_family_t family = sockaddr_ptr->sa_family;
                        struct sockaddr_in *addr4 = (struct sockaddr_in*)sockaddr_ptr;
                        struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)sockaddr_ptr;
                        switch (family) {
                                case AF_INET:
                                        inet_ntop(AF_INET, &addr4->sin_addr, netip, INET6_ADDRSTRLEN);
                                        break;
                                case AF_INET6: