接口
字符串转 in_addr:
//head file
#include <arpa/inet.h>
//port
int inet_aton(const char* strptr, struct in_addr* addrptr);
in_addr_t inet_addr(const char* strptr);
int inet_pton(int family, const char* strptr, void addrptr);
inet_addr 转字符串:
char* inet_ntoa(struct in_addr inaddr);
const char* inet_ntop(int family, void* addrptr,
char* strptr, size_t len);
关于 inet_ntoa 线程安全的问题
inet_ntoa这个函数返回了⼀一个char*, 很显然是这个函数⾃自⼰己在内部为我们申请了一块内存来保存ip的结果. 根据man手册记录,inet_ntoa函数把这个结果放到了静态存储区。
那么我们就要小心了,因为它有可能不是线程安全的,就像strtok函数那样(strtok函数将处理结果放到了静态存储区,会有线程安全的问题)。
虽然笔者在Centos7环境下测试却没有出现线程安全的问题,但是为了保险起见,还是推荐使用inet_ntop函数(这个函数的解决方案和strtok_r类似,由程序员主动提供一个缓冲区来保留函数处理的结果)。
线程安全测试代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
void* func1(void* p){
sockaddr_in *addr = (sockaddr_in*)p;
while(1){
char* ptr = inet_ntoa(addr->sin_addr);
printf("addr1 : %s\n", ptr);
}
return NULL;
}
void* func2(void* p){
sockaddr_in *addr = (sockaddr_in*)p;
while(1){
char* ptr = inet_ntoa(addr->sin_addr);
printf("addr2 : %s\n", ptr);
}
return NULL;
}
int main() {
pthread_t tid1 = 0;
sockaddr_in addr1;
sockaddr_in addr2;
addr1.sin_addr.s_addr = 0;
addr2.sin_addr.s_addr = 0xfffffff;
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;
}
inet_ntop函数用法介绍
函数原型:
const char * inet_ntop(int family, const void *addrptr,
char *strptr, size_t len);
//第一个参数是AF_INET / AF_INET6(支持ipv6)
//第二个参数是in_addr的地址
//第三个参数是由程序员提供的缓冲区
//第四个参数是缓冲区的大小,如果len太小,不足以容纳表达式结果,
//那么返回一个空指针,并设置为errno为ENOSPC。