乐趣区

Linux:netstat 面试答疑

前言
在面试的过程中,总不可避免会问到与 操作系统 和 网络 相关的内容,因为这个确实是工作上经常打交道的内容;
敢打包票,十个计算机网络的面试题,必有几道和 tcp/udp 有关,像什么 tcp 三次握手四次挥手、udp 与 tcp 区别等等。
除了这些知识点,还有一个很常见的,那就是 netstat 了。
为什么会问 netstat?因为有太多的情况是需要它来协助了,比如网络链接异常,所以我一般会从 netstat 开始,由浅入深来考察对方的命令基础和网络基础:
问题 1. 如何查看哪个程序正在监听 xxxx 端口?
如何查看哪个程序正在监听 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. 如何查看当前机器各网络状态的链接个数?
回归主题,上面那道是比较简单的题目,我们接下来要问
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 链接信息的工作原理是什么?
如果这两题目都回答过来了,那就代表基础尚可了,我准备问更加深入的了:
3. netstat 输出 tcp 和 udp 链接信息的工作原理是什么?

我期望的答案:
是解析 /proc/net/tcp、/proc/net/udp 的结果

考点:单纯问问知识面

接着上面继续提问:
问题 4. netstat 可以找出每个链接对应的哪个程序,是怎么实现的?
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 相互关联得出来的

总结
面试是个既考验广度也考验深度的过程,我们可以不了解高深的知识,但是我们不能停止探索专业的脚步。

退出移动版