前言

说明:

  • demo 基于 Linux。

7. 域名与网络地址

本节主要记录三个名词:DNS、域名及IP。

7.1 IP

IP地址:网络层的主机地址。老生常谈啦

目前分为IPV4和IPV6。

如百度的地址之一:202.108.22.5

7.2 域名

域名就是IP的别名吧,因为人类对数字的记忆较难,所以把某个IP起个别名。

如百度的域名:www.baidu.com

在浏览器地址栏中输入其域名就可以访问到百度的服务器,不用记其IP地址了。

7.3 DNS

DNS 是对IP地址和域名进行相互转换的系统,其核心是 DNS 服务器。

因为 TCP/IP 协议栈中网络层需要的是 IP 地址,而不是域名,所以得需要把域名转换成对于的IP地址。

如图:

7.4 IP地址与域名之间的转换

7.4.1 利用域名获取IP地址

struct hostent
{
char *h_name; /* Official name of host. */
char **h_aliases; /* Alias list. */
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
}; /*
成功时返回 hostent 结构体地址,失败时返回 NULL 指针
*/
#include <netdb.h>
struct hostent *gethostbyname(const char *hostname);

struct hostent

  • h_name:该变量中存有官方域名(Official domain name)。官方域名代表某一主页,但实际上,一些著名公司的域名并没有用官方域名注册。
  • h_aliases:可以通过多个域名访问同一主页。同一IP可以绑定多个域名,因此,除官方域名外还可以指定其他域名。这些信息可以通过 h_aliases 获得。
  • h_addrtype:gethostbyname 函数不仅支持 IPV4 还支持 IPV6 。因此可以通过此变量获取保存在 h_addr_list 的IP地址族信息。若是 IPV4 ,则此变量中存有 AF_INET。
  • h_length:保存IP地址长度。若是 IPV4 地址,因为是 4 个字节,则保存4;IPV6 时,因为是 16 个字节,故保存 16。
  • h_addr_list:这个是最重要的的成员。通过此变量以整数形式保存域名相对应的IP地址。另外,用户比较多的网站有可能分配多个IP地址给同一个域名,利用多个服务器做负载均衡,。此时可以通过此变量获取IP地址信息。

7.4.2 利用IP地址获取域名

/*
addr: 含有IP地址信息的 in_addr 结构体指针。为了同时传递 IPV4 地址之外的全部信息,该变量的类型声明为 char 指针
len: 向第一个参数传递的地址信息的字节数,IPV4时为 4 ,IPV6 时为16.
family: 传递地址族信息,ipv4 是 AF_INET ,IPV6是 AF_INET6
成功时返回 hostent 结构体变量地址值,失败时返回 NULL 指针
*/
#include <netdb.h>
struct hostent *gethostbyaddr(const char *addr, socklen_t len, int family);

7.4.3 升级版的API

getaddrinfo() 能够处理 域名到IP服务到端口 这两种转换。可重入的。

getnameinfo() 能够处理 IP到域名端口到服务 这两种转换。可重入的。

#include <sys/socket.h>
#include <netdb.h> int getaddrinfo(const char *restrict nodename, /* host 或者IP地址 */
const char *restrict servname, /* 十进制端口号 或者常用服务名称如"ftp"、"http"等 */
const struct addrinfo *restrict hints, /* 获取信息要求设置 */
struct addrinfo **restrict res); /* 获取信息结果 */ void freeaddrinfo(struct addrinfo *ai); // 需要了解的结构体
struct addrinfo {
int ai_flags; /* 附加选项,多个选项可以使用或操作结合 */
int ai_family; /* 指定返回地址的协议簇,取值范围:AF_INET(IPv4)、AF_INET6(IPv6)、AF_UNSPEC(IPv4 and IPv6) */
int ai_socktype; /* enum __socket_type 类型,设置为0表示任意类型 */
int ai_protocol; /* 协议类型,设置为0表示任意类型 */
socklen_t ai_addrlen; /* socket address 的长度 */
struct sockaddr *ai_addr; /* socket address 的地址 */
char *ai_canonname; /* Canonical name of service location. */
struct addrinfo *ai_next; /* 指向下一条信息,因为可能返回多个地址 */
}; // The sockaddr structure is used to define a socket address which is used in the bind(), connect(), getpeername(), getsockname(), recvfrom(), and sendto() functions.
struct sockaddr
{
sa_family_t sa_family; //Address family.
char sa_data[14]; // Socket address (variable-length data).
};
// 该结构体一般都会转为
struct sockaddr_in
{
sa_family_t sin_family; //地址族(Address Family)
uint16_t sin_port; //16 位 TCP/UDP 端口号
struct in_addr sin_addr; //32位 IP 地址
char sin_zero[8]; //为了保证其大小一致,目前不使用
};
struct in_addr
{
in_addr_t s_addr; //32位IPV4地址
}

getaddrinfo() 参数说明:

  • nodename:主机名:

    • 域名:"www.baidu.com"
    • 数字化的地址字符串IPv4的点分十进制串:"192.168.1.100"
    • 数字化的地址字符串IPv6的16进制串:"2000::1:2345:6789:abcd"
    • 注意:如果 ai_flags 中设置了 AI_NUMERICHOST 标志,那么该参数只能是数字化的地址字符串,不能是域名。该标志的作用就是阻止进行域名解析。
  • servname:服务名。
    • 可以是十进制的端口号("8080")字符串,也可以是已定义的服务名称,如"ftp"、"http"等。
    • 如果为NULL,那么返回的socket地址中的端口号不会被设置。
    • 注意:如果 ai_flags 设置了 AI_NUMERICSERV 标志并且该参数未设置为NULL,那么该参数必须是一个指向10进制的端口号字符串,不能设定成服务名,该标志就是用来阻止服务名解析。
  • hints:该参数指向用户设定的 struct addrinfo 结构体。
    • 只能设定该结构体中 ai_family、ai_socktype、ai_protocol 和 ai_flags 四个域。
    • 其他域必须设置为0 或者 NULL。
    • 结构体参数参考上面代码注释。
  • res:该参数获取一个指向存储结果的 struct addrinfo 结构体列表,使用完成后调用 freeaddrinfo() 释放存储结果空间。
  • 返回:
    • 0:成功。
    • 其它错误标志:失败。

getnameinfo() 能够处理 IP到域名端口到服务 这两种转换。可重入的。

#include <netdb.h>
/**
* @param addr,输入参数。struct addrinfo中的struct sockaddr
* @param addrlen,输入参数。struct addrinfo中的socklen_t
* @param host,输出参数。IP地址
* @param hostlen,输入参数。告诉函数host的大小
* @param serv,输出参数。端口号
* @param servlen,输入参数。告诉函数servlen的大小
* @param flags,输入参数。告诉函数struct sockaddr的处理方式
*
* @return 返回零则成功。
*/
int getnameinfo(const struct sockaddr *sockaddr,
socklen_t addrlen,
char *host,
size_t hostlen,
char *serv,
size_t servlen,
int flags);

7.5 小知识

DNS主要基于UDP。

目前全球只有13台域名根服务器。

并不是每条DNS查询都要到达根服务器的,查询是逐级查询,各级都有缓存表,先查缓存表中的,没有再往上报。

8.8.8.8是Google公司提供的免费DNS服务器的IP地址。

也可以指定本地的DNS服务器,只要能解析域名与IP即可。

参考

参考

【网络编程】TCPIP-7-域名与网络地址的更多相关文章

  1. linux c 网络编程:用域名获取IP地址或者用IP获取域名 网络地址转换成整型 主机字符顺序与网络字节顺序的转换

    用域名获取IP地址或者用IP获取域名 #include<stdio.h> #include<sys/socket.h> #include<netdb.h> int ...

  2. 网络编程中获取域名和id的方法

    package com.lanqiao.java.test; import java.net.InetAddress;import java.net.UnknownHostException; pub ...

  3. Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip

    获取本地 ip 地址,mac,通过域名获取对应的 ip, 是网络编程可能遇到的比较常见的操作了,所以总结如下(封装了3个函数), 直接上代码: #include <stdio.h> #in ...

  4. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  5. 从零开始学Python第八周:网络编程基础(socket)

    Socket网络编程 一,Socket编程 (1)Socket方法介绍 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Soc ...

  6. python之网络编程

    本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用 ...

  7. python 网络编程

    一.网络知识的一些介绍 socket是网络连接端点.例如当你的Web浏览器请求www.pythontik.com上的主页时,你的Web浏览器创建一个socket并命令它去连接www.pythontik ...

  8. php网络编程

    php面试题之三--PHP网络编程(高级部分) 三.PHP网络编程 [!!!]1.禁用COOKIE后SEESION还能用吗?(51.com笔试题) 可以,COOKIE和SESSION都是用来实现会话机 ...

  9. php面试题之三——PHP网络编程(高级部分)

    三.PHP网络编程 [!!!]1.禁用COOKIE后SEESION还能用吗?(51.com笔试题) 可以,COOKIE和SESSION都是用来实现会话机制的,由于http协议是无状态的,所以要想跟踪一 ...

随机推荐

  1. XCTF 3rd-GCTF-2017 hackme

    一.查壳的老生常谈了..2分的题目就不多bb了. 二..elf文件,拖入ida,直接查找字符串,找到对应的函数 三.直接分析: 这里讲道理我当时很懵逼,因为进去这个函数后,发现伪码非常复杂,这里困了挺 ...

  2. php微信jsapi支付 支付宝支付 两码合一

    产品开会提出了这样的需求:一个二维码可以微信支付也可以支付宝支付 经过自己的钻研以及询问技术高人(本人代码一般般)和网上搜索 最终实现其功能  我用微信jsapi 和 支付宝网页支付 其实并不怎么难: ...

  3. ABP Framework 为什么好上手,不好深入?探讨最佳学习姿势!

    离写上一篇经验总结 ABP Framework 研习社经验总结(6.28-7.2) ,已经过去两周. ABP Framework 研习社(QQ群:726299208) 最近一周,又迎来了很多新伙伴,成 ...

  4. 14个Java技术网站,程序员必备!

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员.我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验. 程序员都是无师自通?这就有点胡 ...

  5. ESP32省电模式连接WIFI笔记

    基于ESP-IDF4.1版本 main.c文件如下: #include <string.h> #include "freertos/FreeRTOS.h" #inclu ...

  6. 利用C语言判定用户输入数据从而给出结果(利用判定用户体重范围)同求最优解!!!

    例子: 要求:医务工作者通过广泛的调查和统计分析,根据成人的身高与体重因素给出了按"体质指数"进行判断的方法,具体如下: 体质指数t=体重 w/(身高h)2(w的单位为kg,h的单 ...

  7. SpringBoot缓存管理(三) 自定义Redis缓存序列化机制

    前言 在上一篇文章中,我们完成了SpringBoot整合Redis进行数据缓存管理的工作,但缓存管理的实体类数据使用的是JDK序列化方式(如下图所示),不便于使用可视化管理工具进行查看和管理. 接下来 ...

  8. WIN10 网卡驱动异常代码56的问题及解决方法

    故障描述: 原来使用正常的一个微机室,突然一天控制端主机网络连接异常,平时的网络控制软件无法使用.检查网络配置正常,网络诊断.修复.将网卡禁用也没有效果:后来删除网卡想重装,则恶运开始,无法安装驱动: ...

  9. C语言枚举类型

    在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等.以每周七天为例,我 ...

  10. 用Python分析下王小波与李银河写情书最爱用哪些词

    作家王小波其实也是我国最早期的程序员,突发奇想,王小波写情书最喜欢用哪些词呢?用Python词云分析下! 直接上代码吧,有注释很好理解.输出的图片设置的比较大,所以运行的比较慢,可以适当把图片尺寸改小 ...