在网络编程中, 经常会将网络字节转为本地字节或者将本地字节转为网络字节, 但是如果每次我们都是都通过htonl, ntohl函数需要将10进制转为整数, 甚至还用将字符串转为整数, 再转为网络字节, 或者反过来都是很麻烦的. 还好linux都是提供很方便的函数让两者之间进行转换.

转换函数

linux提供了多种函数满足我们任何转换的需求, 这都是inet_xxx族系列

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h> int inet_aton(const char *ip, struct in_addr *inp); // 本地转网络 char * inet_ntoa(struct in_addr inp); // 网络转本地 in_addr_t inet_addr(const char *ip); // 返回网络字节 in_addr_t inet_network(const char *ip); // 返回本地字节

接下来我们来在分析一下这几个函数

1. inet_aton函数

将点分十进制IP转化为网络字节序存放在inp中, 并返回该网络字节序对应的整数.

int inet_aton(const char *ip, struct in_addr *inp);

失败 : 返回0.

成功 : 返回IP对应的网络字节序的数.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h> // 传入 127.0.0.1
int main(int argc, char *argv[])
{
if(argc != 2)
exit(-1); struct in_addr addr;
if(inet_aton(argv[1], &addr) == 0)
exit(-1);
printf("0x%08x\n", addr.s_addr); // 0x0100007f exit(EXIT_SUCCESS);
}

2. inet_ntoa函数

将一个32位网络字节序的二进制IP地址转换成相应的点分十进制的IP地址.

char *inet_ntoa(struct in_addr inp);

失败 : 返回NULL.

成功 : 返回字符串指针.

注意 : 该函数不是线程安全函数, 不可重入. 因为不同线程调用会覆盖掉其他线程的缓冲区.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h> int main(int argc, char *argv[])
{
struct in_addr net_addr;
net_addr.s_addr = 0x0100007f; // 127.0.0.1
char *host_addr; host_addr = inet_ntoa(net_addr);
printf("%s\n", host_addr); // 127.0.0.1 exit(EXIT_SUCCESS);
}

3. inet_addr函数

将一个点分十进制转换网络字节序IP.

in_addr_t inet_addr(const char *ip);

失败 : 返回INADDR_NONE. 部分手册上返回的是-1, 这个问题与inet_network一样了.

成功 : 返回网络字节IP.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h> // 输入 127.0.0.1
int main(int argc, char *argv[])
{
in_addr_t addr; addr = inet_addr(argv[1]);
printf("0x%08x\n", addr); // 0x0100007f exit(EXIT_SUCCESS);
}

4. inet_network函数

将点分十进制IP转化为主机字节序

in_addr_t inet_network(const char *ip);

失败 : 返回-1.

成功 : 返回主机对应的数.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> // 输入 127.0.0.1
int main(int argc, char *argv[])
{
in_addr_t addr; addr = inet_network(argv[1]);
printf("0x%08x\n", addr); // 0x7f000001 exit(EXIT_SUCCESS);
}

该函数在某些情况下并不正确, 如果IP地址是255.255.255.255返回的则是0xffffffff, 转为十进制就是-1. 分不清出-1表示的是错误的返回值还是IP地址. 可以使用inet_pton()inet_ntop()函数来代替, 这里就不详细的分析了, 有兴趣的可以自己查一下.

总结

本节分析了4个函数, 重点需要掌握的是inet_aton函数.

  • 4个函数使用, 以及返回值
  • inet_network返回值的问题
  • inet_ntoa并不是线程安全的函数

inet_XX族函数的更多相关文章

  1. Linux学习笔记(8)-exec族函数

    昨天学习了Linux下的进程创建,创建一个进程的方法极为简单,只需要调用fork函数就可以创建出一个进程,但是-- 介绍fork()函数的时候提到,在创建进程后,子进程与父进程有相同的代码空间,执行的 ...

  2. R-- Apply族函数

    APPLY族函数: apply(x,a,f) 对矩阵或数据框的某一维度作用函数fx为矩阵或数据框:a为1代表行,a为2代表列:f为作用函数. lapply(x,f) 对x的每一个元组作用函数f,结果以 ...

  3. exec族函数详解及循环创建子进程

    前言:之前也知道exec族函数,但没有完全掌握,昨天又重新学习了一遍,基本完全掌握了,还有一些父子进程和循环创建子进程的问题,还要介绍一下环境变量,今天分享一下. 一.环境变量 先介绍下环境的概念和特 ...

  4. 【Linux 进程】exec族函数详解

    exec族的组成: 在Linux中,并不存在一个exec()的函数形式,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **e ...

  5. R中的apply族函数和多线程计算

    一.apply族函数 1.apply  应用于矩阵和数组 # apply # 1代表行,2代表列 # create a matrix of 10 rows x 2 columns m <- ma ...

  6. 从0开始自己用C语言写个shell__01_整体的框架以及fork和exec族函数的理解

    最近才忙完了一个操作系统的作业,让我们用C语言实现一个Shell.总的来说,其实就是让我们 对系统调用有比较深的了解. 首先 介绍一下我的Shell 所实现的功能.1.运行可执行程序 即输入某个 标志 ...

  7. Linux-exec族函数

    1.为什么需要exec族函数 (1).fork子进程是为了执行新程序(fork创建子进程后,子进程和父进程同时被OS调度执行,因此子程序可以单独的执行一个程序,这样程序宏观上将会和父进程程序同时进行) ...

  8. Linux exec族函数解析

    背景 在提到 vfork 函数时,我们提到了这个概念.为了更好地学习与运用,我们对exec族函数进行展开. exec函数族 介绍 有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中 ...

  9. vector族函数

     本文原创,转载请注明出处,本人Q1273314690 vector(mode = "logical", length = 0) as.vector(x, mode = " ...

随机推荐

  1. 暴力解hdu4930Fighting the Landlords

    #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> us ...

  2. 我所未知的 typeof 现象

    一.一些基本使用测试 从上述可以看出: 1.判断一个 变量 是不是对象类型,不能只用 typeof 运算符: 2.它的返回值一直是一个字符串: 3.尽管 typeof null === 'object ...

  3. HDU 1159 Common Subsequence (动规+最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. PHP数字左侧自动补零

    1.输出数字为001,002... <?php $number=0; if($number<100) { $number=$number+1; $txt=sprintf("%03 ...

  5. 20170620_javaweb_小结

    01.session失效的方式 02. session和cookie的区别 03.jsp九大内置对象,意义 以及对应的java类 04.转发和重定向 05.jsp的执行过程 和 生命周期 06.实现s ...

  6. table形式的列表页面显示

    (该案例在项目中的reserve_bchmc.html,其对应的后台在CountBean中) 先看一下效果图: 该列表页面并不是用easyUI中的datagrid实现的,而是用table实现页面显示的 ...

  7. P2120 [ZJOI2007]仓库建设 斜率优化dp

    好题,这题是我理解的第一道斜率优化dp,自然要写一发题解.首先我们要写出普通的表达式,然后先用前缀和优化.然后呢?我们观察发现,x[i]是递增,而我们发现的斜率也是需要是递增的,然后就维护一个单调递增 ...

  8. 杂项:LDAP

    ylbtech-杂项:LDAP 1.返回顶部 1. LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP.它是基于X. ...

  9. MSP430 使用时 RST引脚一定拉高

    因为这次省去了RESET按键,RST没做任何处理,程序下载完之后插上电池无法运行,最终原因:RST引脚没有拉高.呼呼切记啊

  10. IDEA Spark Streaming 操作(文件源)

    import org.apache.spark.SparkConf import org.apache.spark.streaming.{Seconds, StreamingContext} obje ...