Linux:netstat 面试答疑
前言
在面试的过程中,总不可避免会问到与 操作系统 和 网络 相关的内容,因为这个确实是工作上经常打交道的内容;
敢打包票,十个计算机网络的面试题,必有几道和 tcp/udp 有关,像什么 tcp三次握手四次挥手、udp 与 tcp 区别等等。
除了这些知识点,还有一个很常见的,那就是 netstat 了。
为什么会问 netstat? 因为有太多的情况是需要它来协助了,比如网络链接异常,所以我一般会从 netstat 开始,由浅入深来考察对方的命令基础和网络基础:
问题1. 如何查看哪个程序正在监听 xxxx 端口?
我期望的答案:
netstat -antlp | grep xxxx 考点:除了写出命令,还要解释上面的选项,如 -a、-n、-t、-l、-p 分别是代表什么意思?
有些童鞋可能不理解,为什么记一个命令还需要记选项含义?
其实这个问题是见仁见智的,我个人认为记住常用的选项首先能够加快使用命令的效率,其次,当你敲完一段命令,你可以在意识中就能明白预期会有什么结果,就好像每人都看过关于删库的段子: rm -rf
。
这个命令组合固然可怕,但是我们却不得不去使用,那么如何使用能将危险锁在笼子里才是我们应该去考虑的问题,想解决这个问题,很显然我们就得先去明白 -r 和 -f 是什么含义,看了 man 文档:
OPTIONS Remove (unlink) the FILE(s). -f, --force ignore nonexistent files and arguments, never prompt -r, -R, --recursive remove directories and their contents recursively
组合起来的意思就是:敲入 rm -rf
,系统就会开始递归地强制的删除东西,等我们反应过来,就是删得七七八八了。
我们可以不用把所有选项全部背下来,但是起码自己写出的命令、选项是什么含义得知道。世上是木有后悔药的,所以在每执行一个命令,都应该对自己负责。
回归主题,上面那道是比较简单的题目,我们接下来要问
问题2. 如何查看当前机器各网络状态的链接个数?
为了避免死记硬背格式,我直接贴出 netstat -ant 的输出
# netstat -ant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:32200 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 1 0 110.82.143.62:50430 110.82.143.62:80 CLOSE_WAIT tcp 0 0 110.130.165.132:45937 110.200.115.132:27017 ESTABLISHED tcp 0 0 110.130.165.132:58529 110.200.115.132:27017 ESTABLISHED tcp 0 0 110.130.165.132:45932 110.200.115.132:27017 ESTABLISHED tcp 0 0 110.120.165.132:45513 110.90.36.54:27017 ESTABLISHED tcp 1 0 110.82.23.62:44746 110.82.43.62:80 CLOSE_WAIT tcp 1 0 110.82.23.62:39068 110.82.43.62:80 CLOSE_WAIT
我期望的答案:
netstat -ant | awk 'NR>2{state[$NF]++}END{for(i in state) print i, state[i]}' 考点:netstat 和 awk 的搭配使用(awk 写法没强制规定,只要能出结果就好,但是肯定命令越少越优)
如果这两题目都回答过来了,那就代表基础尚可了,我准备问更加深入的了:
问题3. netstat 输出 tcp 和 udp 链接信息的工作原理是什么?
我期望的答案:
是解析 /proc/net/tcp、 /proc/net/udp 的结果 考点:单纯问问知识面
接着上面继续提问:
问题4. netstat 可以找出每个链接对应的哪个程序,是怎么实现的?
这道题已经是比较接近核心了,所以这道题如果能回答上,那肯定就是有真的深入了解过 netstat,可能有自我驱动、自我学习的能力,潜质是挺好的。
简要分析:
在 linux 系统上,任何东西都可以看成是一个文件,对于 socket 也是如此。 我们可以在每个程序的 fd 目录,也就是 /proc/{pid}/fd 下可以看到每个进程打开的文件: ls -l /proc/22134/fd total 0 lr-x------ 1 root root 64 Mar 13 16:20 0 -> pipe:[667139080] l-wx------ 1 root root 64 Mar 13 16:20 1 -> pipe:[667139081] l-wx------ 1 root root 64 Mar 13 16:20 10 -> pipe:[669473083] lrwx------ 1 root root 64 Mar 13 16:20 11 -> socket:[669471737] lrwx------ 1 root root 64 Mar 13 16:20 12 -> socket:[669468288] 其中 socket:[669468288] 就代表这个进程的其中一个网络链接,而中括号里面的 669468288 就是该 socket 的 inode 编号。 我们可以根据这个 inode 编号,在刚才提到的 /proc/net/tcp 和 /proc/net/udp 文件里面去查找: # grep 669468288 /proc/net/tcp 8: 0100007F:0004 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 669468288 1 ffff8806545e9100 100 0 0 10 0 # grep 669468288 /proc/net/udp 无结果
结合第三题的问题和上面的分析,这道题我期望的答案:
1. netstat 解析/proc/net/tcp、 /proc/net/udp; 2. 遍历 /proc/{pid}/fd 下的每个文件拿到每个 socket 的 inode; 3. 1 和 2 相互关联得出来的
基本上问到这里就差不多了,但是有时候比较“潮流“的我们,会使用 ss 代替 netstat。所以也要象征性跟上潮流地问几句。
问题5. 有了解过 ss 吗?ss 和 netstat 的工作原理有什么区别吗?
这个 ss 可能会有点歧义,因为绝大部分会把他理解成 shadowscok(翻墙的小工具), 所以这边需要扫盲下。
此 ss 非彼 ss, 可以简单了解下该命令:https://www.cnblogs.com/ftl10...。
对于 ss 因为用法、参数含义都和 netstat 的很相似,所以一般不会问参数什么的,而是会问另一个话题:
为什么 ss 比 netstat 快?
想解答这个问题,必不可少得去知道 ss 的实现原理,这个也就是相当于上面的问题了:它们两者有什么区别?
在上面的问题3. netstat 工作原理已经道出:是通过 /proc/net/{udp|tcp} 这个文件解析出来的,
而 ss 虽然也有这种方式,但是只是一个backup 方案而已,它主要方法是通过 linux netlink 来获取网络链接信息;
关于如何通过 netlink 获取网络链接,下面也给出一个很详细很具体的文档:
Linux 用户态与内核态的交互——netlink 篇:http://bbs.chinaunix.net/thre...
github 上面的一个测试case(不是我写的,我也想我有那能力,哭。。):
https://github.com/kristrev/i...
所以我期望的答案:
1. netstat 是通过 /proc/net/ 下相关的文件解析获取的; 2. ss 主要是通过 netlink 的 tcp_diag 来获取的,如果系统不支持 netlink,则会和 netstat 相似的读取 /proc/net/ 下的相关文件; 3. 而对于 -p 参数,也就是将链接关联到对应的进程,都是一样的需要遍历 /proc/pid/fd,找出 socket 文件 inode,然后再对应回去的。
总结
以上就是 netstat 相关的面试题和涉及到的知识点,仅仅只是抛砖引玉,因为每个问题都可以挖掘出很多。我们可以在这个基础上去“武装”自己,至少不在这里掉坑;
面试是个既考验广度也考验深度的过程,我们可以不了解高深的知识,但是我们不能停止探索专业的脚步。
欢迎各位大神指点交流, QQ讨论群: 258498217
转载请注明来源: https://segmentfault.com/a/11...