【Linux网络编程】域名转IP后的一些深层(计算机底层)的思考
文章目录
- 以下代码运行于64位Linux系统中
- 先看一下代码样本
- 思考
- 说这些是为了证明什么呢?
- 结语
以下代码运行于64位Linux系统中
先看一下代码样本
HOSTENT *H = gethostbyname("www.csdn.net");
char **p = H->h_addr_list;
SOCKADDR_IN info;
while(*p) {memcpy(&info.sin_addr, *p, 4);cout << inet_ntoa(info.sin_addr) << endl;++p;
}
- 第一行创建了一个结构体指针
H
,指向函数gethostbyname
,并传入了一个参数(即域名) - 第二行创建了一个指向指针的指针
p
,用来储存指针H
中存放的所有IP地址。 - 第三行创建了一个结构体
info
- 第四行是一个while语句,用来判断p中第一个元素是否为空指针,否就继续执行
- 第五行是将
p
中第一个元素从内存层面复制到结构体info
成员sin_addr
的地址中 - 第六行是将
info.sin_addr
中存放的IP地址二进制值转为一个char指针
并被打印屏幕上。
思考
这段代码当初是我刚学网络编程时抄的一位程序员的,但是由于目前我的技术水平有了质的飞跃,于是发现了一些问题。
也不能说是问题吧,毕竟这段代码完全没有问题(除非你把它原封不动的抄到Windows上执行,因为还需要初始化WSADATA)。
可以看到第三行声明了一个结构体变量info(struct sockaddr_in),因为在上述代码中我们是要用它来暂时性的储存IP地址的,所以才创建了它。
但其实,完全没必要声明(创建)这个变量,接下来看我说为什么。
大家都知道指针是指向一个内存地址的,也就意味着你可以用指针查看你权限范围内的内存中所有数据。
这是什么意思呢?
char c1 = 'A'; // 声明一个字符型变量c1并赋值为字母A
char c2 = 'B'; // 声明一个字符型变量c2并赋值为字母B
char *p = nullptr; // 声明一个指针p,暂时将它赋值为空size_t c1_addr = (size_t)&c1; // 将c1的内存地址数字存入变量c1_addr
size_t c2_addr = (size_t)&c2; // 将c2的内存地址数字存入变量c2_addrif(c1_addr < c2_addr) // 判断哪个地址值最小,将p指向最小的地址值的变量p = &c1;
elsep = &c2;cout << *(p + 1) << endl; // 打印为A
你无论如何怎么执行,它永远只会输出A,为什么呢?
变量c1的地址为0x0000002
变量c2的地址为0x0000001
c1被赋值为了A
c2被赋值为了B
指针p永远指向最小的那个内存地址,此处就指向了c2的内存地址,我们将p指向的地址加了1字节,也就变成了0x0000002,而这段地址中储存的值为A,这就是为什么这段代码永远只输出A的原因。
说这些是为了证明什么呢?
为了证明所有数据你都可以通过指针操控,也就意味着我们一开始的那段代码,其实根本不需要多声明一个变量info。
因为在第二行char **p = H->h_addr_list;
执行之后,此域名下所有的IP地址已经存入内存了。
而我们又知道,一字节为8比特,可以存放0~255之间所有的数字。
那IP地址是怎么组成的呢?
也就是4个0~255之间的数字组合在一起。
也就意味着他们在内存中的表现其实已经是一个完整的地址了,不需要再通过inet_ntoa
等函数进行转换了。
为什么呢?
一开始那段代码,只执行前两行的话,p的第一个元素指向的地址中的数据是3c cd ac 02
,而哪个域名的IP地址是60.205.172.2
,有没有发现什么奇妙的地方?
没错,IP地址已经出来了,只不过它是以十六进制的形式出现的。
如果你还没明白我想表达的意思,你可以执行一下下面这段代码。
unsigned char ip[4] = {0x3c, 0xcd, 0xac, 0x02};
printf("%d.%d.%d.%d\n", *ip, *(ip+1), *(ip+2), *(ip+3));
结语
C语言是一个非常灵活非常不可思议的语言,只要你掌握好了它,那么你就可以在计算机中做任何你想做的事情。
【Linux网络编程】域名转IP后的一些深层(计算机底层)的思考相关推荐
- Linux网络编程 - 域名(DNS)及网络地址
一 域名系统 DNS(Domain Name System,域名系统) 是对IP地址和域名进行互相转换的系统,其核心是 DNS 服务器. 1.1 什么是域名 提供网络服务的服务器端也是通过IP地址区分 ...
- Linux网络编程——基于tcp/ip的模拟聊天(文件传输)工具
开发平台:Linux 开发工具:Ubuntu, sourceInsight4.0 项目介绍: 本项目基于TCP/IP协议创建一个网络通信系统,可以实现客户之间的聊天通信以及文件传输,同时利用进程实现多 ...
- Linux网络编程基础
2019独角兽企业重金招聘Python工程师标准>>> (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的 ...
- Linux网络编程入门
(一)Linux网络编程--网络知识介绍 linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. ...
- Linux网络编程 入门
Linux网络编程入门 (转载) (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...
- Linux 网络编程 TCP
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客 ...
- Linux网络编程入门 (转载)
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客 ...
- Linux网络编程基础知识
Linux网络编程基础知识 1. 协议的概念 1.1 什么是协议 1.2 典型协议 2 网络应用程序设计模式 2.1 C/S模式 2.2 B/S模式 2.3 优缺点 3 分层模型 3.1 OSI七层模 ...
- Proxy源代码分析--谈谈如何学习linux网络编程
Linux是一个可靠性非常高的操作系统,但是所有用过Linux的朋友都会感觉到,Linux和Windows这样的"傻瓜"操作系统(这里丝毫没有贬低Windows的意思,相反这应该是 ...
最新文章
- jquery倒计时插件可自定义多个倒计时间
- CNN tflearn处理mnist图像识别代码解说——conv_2d参数解释,整个网络的训练,主要就是为了学那个卷积核啊。...
- tomact如何处理一个http请求?
- Chart of Accout-科目表
- php验证码切换不刷新页面,Yii2解决验证码点击、刷新页面不刷新问题
- 二分枚举+贪心(nyist疯牛)
- 2015蓝桥杯省赛---java---A---3(九数分三组)
- symbian 中自动寻找cmwap连接点,通杀uiq 2nd 3nd和s60 2nd 3nd 5nd
- date转timestamp格式_技术分享 | MySQL:timestamp 时区转换导致 CPU %sy 高的问题
- Pytest自定义标记mark及特定运行方式
- C++设计模式-策略模式(Strategy)基本轮廓
- php常见预定义常量,php跨平台小结 常用预定义常量
- 【体系结构】Oracle段区块的个人理解
- 【HDU】4391 Paint The Wall
- C语言齿轮参数计算程序,C语言程序实现齿轮基本参数几何尺寸计算.pdf
- eclipse svn忽略指定文件或文件夹
- 怎么样修改vlan从trunk到access模式,提示renew the default configurations
- 软件过程管理在软件项目中的作用
- 加拿大大学商用计算机专业,加拿大大学计算机专业排名一览
- html 5标签读音,radish读音
热门文章
- vue el-table 表格宽度无法缩小自适应
- 数据交换方式(电路交换、数据报交换、分组交换)
- MySQL面试:索引为啥使用B+树而不是B树
- C语言 数字实现字母表 链表实现字母表
- Google Play评论抓取
- ubuntu18.04解决wps缺字体问题
- 当兵的目标和计划_最新大学生征兵工作计划
- 产品的概念:提出与筛选--第三章人人都是产品经理
- 7.camera驱动06-自己实现v4l2驱动-虚拟摄像头
- java计算机毕业设计基于安卓Android的禁毒宣传APP(源码+系统+mysql数据库+Lw文档)