socket编程 & 地址转换函数

接口

字符串转 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。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值