Linux:netstat 面试答疑

码中飞翔 2019-07-01

前言

在面试的过程中,总不可避免会问到与 操作系统网络 相关的内容,因为这个确实是工作上经常打交道的内容;

敢打包票,十个计算机网络的面试题,必有几道和 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...

相关推荐

Linuxer / 0评论 2016-08-10