最近在看CSAPP的网络编程小节,盯着getaddrinfo这个api看了两天,总算是琢磨出了为何要引入这样复杂的一个api。

其依赖头文件如下,涉及的3个接口如下

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>int getaddrinfo(const char *host, const char *service,const struct addrinfo *hints,struct addrinfo **result);void freeaddrinfo(struct addrinfo *result);const char *gai_strerror(int errcode);

就我个人理解,引入getaddrinfo有以下三点好处:

1. 写网络相关代码时不需要将ipv4或者ipv6相关的预定义常数指明,通过查询填入。

2. 不用操心字节序问题。

首先说第一点,如果写代码时使用 AF_INET这样指明ipv4协议的预定义常数的话,相应代码只能用于ipv4。同理,如果使用了AF_INET6,那么代码只能用于ipv6.

为了使代码既能用于ipv4又能用于ipv6的话,当需要指明下图中结构体socketaddr_in里的协议族时sin_family,可以避免硬编码为AF_INET或AF_INET6,而是采用getaddrinfo去查询,然后填入,查询结果是ipv4就填AF_INET,查询结果是ipv6就填AF_INET6。因为没有深入底层源码,查询具体如何实施的不太清楚,初步推测可能是通过访问当前网段的DNS server来获取相应的信息。

/*IP socket address structure*/
struct sockaddr_in{uint16_t            sin_family;uint16_6            sin_port;struct in_addr      sin_addr;unsigned char       sin_zero[8];
};

再说第二点,在上图中,sin_port 和 sin_addr 都是需要按照大端法在网络中传输的。

简单说下大小端法的区分,设整数 v 占 4个字节 为0x12345678,  v的地址&v指 栈或堆或.data段中(取决于我们声明的方式)的最低地址,如下图

virtual memory:

0x40000F:

0x40000E:

0x40000D:

0x40000C:

如果变量v放在这4个字节里,则其地址 &v 为0x40000C,如果0x40000C里存的是最低有效位0x78则称其为小端法,这也是大多数机器的做法,如果0x40000C里存的是最高有效位0x12则是大端法。

假设port 为 80,80的16比特表示为  00000000  01010000,其16进制表示为 0x00 0x50

在存储时,声明一个结构体 struct sockaddr_in addr_example; 我们想将addr_example的端口号设为80。

如果我们的机器是大端法,那直接通过以下语句即可,

addr_example.sin_port = 80

但如果我们的机器是小端法,则需要通过以下4句代码来将 结构体里的2字节端口号设为指定的80;

char *temp = (char *)(addr_example.sin_port)
*temp = 0x00;
temp++;
*temp = 0x50;

这是非常麻烦的,通过查询getaddrinfo并赋值的方式,不管我们的机器是大端法还是小端法,它都将相应的sin_port设置为了大端法表示下的80,即通过getaddrinfo查询并复制后,如下检测为真。

* ((char *)(addr_example.sin_port)) == 0x00 &&* ((char *)(add_example.sin_port) + 1) == 0x50;

最后就是为啥 声明一个 struct sockaddr *result 而传了&result,

如果api 里声明成 struct sockaddr *result的话,我们想要修改这个结构体就需要先声明并且定义一个 struct sockaddr result,然后把其地址传进去。

但是如果我们想要在接口内修改一个 struct sockaddr * 类型,那我们就必须传一个 struct sockaddr ** 类型,

浅谈getaddrinfo相关推荐

  1. 浅谈go语言交叉编译

    浅谈go语言交叉编译 基础 cgo cgo设置编译和链接参数 静态库和动态库 静态库 动态库 静态编译 cgo的内部连接和外部连接 internal linking external linking ...

  2. 浅谈MySQL存储引擎-InnoDBMyISAM

    浅谈MySQL存储引擎-InnoDB&MyISAM 存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式 ...

  3. 【大话设计模式】——浅谈设计模式基础

    初学设计模式给我最大的感受是:人类真是伟大啊!单单是设计模式的基础课程就让我感受到了强烈的生活气息. 个人感觉<大话设计模式>这本书写的真好.让貌似非常晦涩难懂的设计模式变的生活化.趣味化 ...

  4. 学校计算机机房好处,浅谈学校计算机机房维护

    浅谈学校计算机机房维护    现在的学校机房都配置了数量较多的计算机,而且机房的使用非常频繁.对于怎样维护好计算机,特别是计算机软件系统,对广大计算机教师来说是一个很重要且非常现实的问题.下面就本人在 ...

  5. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  6. mybatis与php,浅谈mybatis中的#和$的区别

    浅谈mybatis中的#和$的区别 发布于 2016-07-30 11:14:47 | 236 次阅读 | 评论: 0 | 来源: 网友投递 MyBatis 基于Java的持久层框架MyBatis 本 ...

  7. 浅谈GCC预编译头技术

    浅谈GCC预编译头技术 文/jorge --谨以此文,悼念我等待MinGW编译时逝去的那些时间. 其 实刚开始编程的时候,我是丝毫不重视编译速度之类的问题的,原因很简单,因为那时我用BASICA.后来 ...

  8. 【笔记】震惊!世上最接地气的字符串浅谈(HASH+KMP)

    震惊!世上最接地气的字符串浅谈(HASH+KMP) 笔者过于垃圾,肯定会有些错的地方,欢迎各位巨佬指正,感激不尽! 引用:LYD的蓝书,一本通,DFC的讲稿,网上各路巨佬 Luguo id: 章鱼那个 ...

  9. 浅谈几种区块链网络攻击以及防御方案之其它网络攻击

    旧博文,搬到 csdn 原文:http://rebootcat.com/2020/04/16/network_attack_of_blockchain_other_attack/ 写在前面的话 自比特 ...

最新文章

  1. c++ string 拼接_String类5个常见面试题的解答过程和原理
  2. SAP WebService基础知识
  3. 脚本#!/bin/bash的作用
  4. java自定义异常返回_Java自定义异常
  5. 栈的应用实例——计算后缀表达式
  6. LeetCode 696. 计数二进制子串
  7. 美团集群调度系统HULK技术演进
  8. 针对提高48V 配电性能的诸多思考!
  9. 中对曲线进行斜率提取_Au中的EQ处理方法——图形均衡器和参数均衡器
  10. java 选中指定文件_Java如何打开一个文件夹并选中指定文件
  11. 【报告分享】2020年中国知识图谱行业研究报告.pdf(附下载链接)
  12. hdu 1054 Strategic Game 树形dp基础模板
  13. slam十四讲第十讲:找不到 g2o_viewer
  14. Java Main 如何是如何被执行的?
  15. 土木保研可以跨计算机专业吗,本科土木跨考计算机专业研究生可行吗?本科土木跨考计算机专业研...
  16. ERROR 1366 (HY000): Incorrect string value: ‘\xE8\xB5\xB5\xE9\x9B\xB7‘ for column ‘s_name‘ at row 1
  17. 计算机英语nic,计算机与网络英语词汇(N2)
  18. 反射机制的优点与缺点
  19. mysql 查询出现次数最多的_MySQL查询重复出现次数最多的记录
  20. js中push方法小结

热门文章

  1. 通过四个多月的时间,我成为了CSDN博客专家
  2. hint: Updates were rejected because the tip of your current branch is behind(git push线上与本地版本冲突问题)
  3. 附录 区块链技术名词与核心原理
  4. python 提取pdf格式电子发票并改名
  5. 用5v1a的充电器给1.2v的镍氢电池充电(充满后可自动断电)或者可以定时
  6. iphone原彩显示对眼睛好吗_iPhone x手机原彩显示烧屏怎么办呢
  7. 金蝶软件系统管理与维护常见问题
  8. SQL进阶教程—自链接的用法
  9. java堆栈异常_Java中获得异常堆栈使用轨迹的方法是。
  10. 论文笔记之Non-Local