Network programming socket (4) - address conversion function

We only introduce socket network programming based on IPv4. The member struct in_addr sin_addr in sockaddr_in represents a 32-bit IP address. In daily life, we often use dotted decimal strings to represent IP addresses. The following functions convert between string representation and in_addr representation.

  • String to in_addr function


  • in_addr to string function



Among them, inet_pton and inet_ntop can not only convert in_addr of IPv4, but also in6_addr of IPv6, so the function interface type is void*.


Code example:

#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;
}

Result presentation:



  • Detailed explanation of inet_ntoa

From the function prototype, we can clearly see that the inet_ntoa function returns a char*, that is, the function internally applies for a piece of memory to save the IP result. So does this memory need to be released manually by the caller?


By querying the man manual, we can learn that the inet_ntoa function puts the returned result in the static storage area, and we do not need to release it manually. When the function is called multiple times, the function result will be overwritten.


Code example:

#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;
}

Result presentation:


From the result, we can clearly see that the result of the second call overwrites the result of the first call.

In the book "Advanced Programming in the Unix Environment", it is clearly stated that inet_ntoa is not a thread-safe function.


Multi-threaded mobilization inet_ntoa code example:

#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;
}

Result presentation:





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325601280&siteId=291194637
Recommended