网络编程套接字(4)——地址转换函数

我们只介绍基于IPv4的socket网络编程,sockaddr_in中的成员struct  in_addr  sin_addr表示32位的IP地址。在日常生活中,我们常用点分十进制的字符串来表示IP地址。以下函数可在字符串表示和in_addr表示之间转换。

  • 字符串转in_addr的函数


  • in_addr转字符串的函数



其中inet_pton和inet_ntop不仅可以转换IPv4的in_addr,还可以转换IPv6的in6_addr,因此函数接口类型为void*。


代码示例:

#include <stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main(){
    struct sockaddr_in addr;
    inet_aton("127.0.0.1",&addr.sin_addr);
    uint32_t* ptr = (uint32_t*)(&addr.sin_addr);
    printf("addr:%x\n",*ptr);
    printf("addr_str:%s\n",inet_ntoa(addr.sin_addr));
    return 0;
}

结果演示:



  • inet_ntoa详解

从函数原型我们可以清楚地看到,inet_ntoa函数返回了一个char*,即该函数自己在内部申请了一块内存来保存IP的结果。那么这块内存是否需要调用者手动释放呢?


通过查询man手册,我们可以了解到,inet_ntoa函数是将返回结果放至静态存储区,不需要我们手动释放。当多次调用该函数时,函数结果会发生覆盖现象。


代码示例:

#include <stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main(){
    struct sockaddr_in addr1;
    struct sockaddr_in addr2;
    addr1.sin_addr.s_addr = 0;
    addr2.sin_addr.s_addr = 0xffffffff;
    char* ptr1 = inet_ntoa(addr1.sin_addr);
    char* ptr2 = inet_ntoa(addr2.sin_addr);
    printf("ptr1:%s,ptr2:%s\n",ptr1,ptr2);
    return 0;
}

结果演示:


通过结果我们可以清楚地看到,第二次调用时的结果将第一次调用时的结果覆盖掉了。

在《Unix环境高级编程》一书中,明确提出了inet_ntoa不是线程安全的函数。


多线程调动inet_ntoa代码示例:

#include <stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>

void* Func1(void* p){
    struct sockaddr_in* addr = (struct sockaddr_in*)p;
    while(1){
        char* ptr = inet_ntoa(addr->sin_addr);
        printf("addr1:%s\n",ptr);
    }
    return;
}

void* Func2(void* p){
    struct sockaddr_in* addr = (struct sockaddr_in*)p;
    while(1){
        char* ptr = inet_ntoa(addr->sin_addr);
        printf("addr2:%s\n",ptr);     
    }
    return;
}

int main(){
    pthread_t tid1 = 0;
    struct sockaddr_in addr1;
    struct sockaddr_in addr2;
    addr1.sin_addr.s_addr = 0;
    addr2.sin_addr.s_addr = 0xffffffff;
    pthread_create(&tid1,NULL,Func1,&addr1);
    pthread_t tid2 = 0;
    pthread_create(&tid2,NULL,Func2,&addr2);
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    return 0;
}

结果演示:





猜你喜欢

转载自blog.csdn.net/Cecilia3333/article/details/80213138