linux端口及查询方法详解

服务是给系统提供功能的,在系统中除了有系统服务,还有网络服务。而每个网络服务都有自己的端口,一般端口号都是固定的。那么,什么是端口呢?

我们知道,IP 地址是计算机在互联网上的地址编号,每台联网的计算机都必须有自己的 IP 地址,而且必须是唯一的,这样才能正常通信。也就是说,在互联网上是通过 IP 地址来确定不同计算机的位置的。

大家可以把 IP 地址想象成家庭的"门牌号码",不管你住的是大杂院、公寓楼还是别墅,都有自己的门牌号码,而且门牌号码是唯一的。

如果知道了一台服务器的 IP 地址,我们就可以找到这台服务器。但是这台服务器上有可能搭建了多个网络服务,比如 WWW 服务、FTP 服务、Mail 服务,那么我们到底需要服务器为我们提供哪个网络服务呢?这时就要靠端口(Port)来区分了,因为每个网络服务对应的端口都是固定的。

比如,WWW 服务对应的端口是 80,FTP 服务对应的端口是 20 和 21,Mail 服务对应的端口是 25 和 110。也就是说,IP 地址可以想象成"门牌号码",而端口可以想象成"家庭成员",找到了 IP 地址只能找到你们家,只有找到了端口,寄信时才能找到真正的收件人。

为了统一整个互联网的端口和网络服务的对应关系,以便让所有的主机都能使用相同的机制来请求或提供服务,同一个服务使用相同的端口,这就是协议。

计算机中的协议主要分为两大类:
  • 面向连接的可靠的TCP协议(Transmission Control Protocol,传输控制协议);
  • 面向无连接的不可靠的UDP协议(User Datagram Protocol,用户数据报协议);

这两种协议都支持 216,也就是 65535 个端口。这么多端口怎么记忆呢?系统给我们提供了服务与端口的对应文件 /etc/services。 查看—下:

[root@localhost ~]#vi /etc/services
…省略部分输出…
ftp-data 20/tcp
ftp-data 20/udp
# 21 is registered to ftp, but also used by fsp
ftp 21/tcp
ftp 21/udp
fsp fspd
#FTP服务的端口
…省略部分输出…
smtp 25/tcp mail
smtp 25/udp mail
#邮件发送信件的端口
…省略部分输出…
http 80/tcp www www-http #WorldWideWeb HTTP
http 80/udp www www-http #HyperText Transfer Protocol
#WWW服务的端口
…省略部分输出…
pop3 110/tcp pop-3
# POP version 3
pop3 110/udp pop-3
#邮件接收信件的端口
…省略部分输出…

网络服务的端口能够修改吗?当然是可以的,不过一旦修改了端口,那么客户机在访问服务器时很难知道服务器对应的端口是什么,也就不能正确地获取服务了。所以,除非在实验环境下,否则不要修改网络服务对应的端口。

查询系统中已经启动的服务

既然每个网络服务对应的端口是固定的,那么是否可以通过查询服务器中开启的端口,来判断当前服务器开启了哪些服务?

当然是可以的。虽然判断服务器中开启的服务还有其他方法(如通过ps命令),但是通过端口的方法查看最为准确。命令格式如下:

[root@localhost ~]# netstat 选项

选项:
  • -a:列出系统中所有网络连接,包括已经连接的网络服务、监听的网络服务和 Socket 套接字;
  • -t:列出 TCP 数据;
  • -u:列出 UDF 数据;
  • -l:列出正在监听的网络服务(不包含已经连接的网络服务);
  • -n:用端口号来显示而不用服务名;
  • -p:列出该服务的进程 ID (PID);

举个例子:

[root@localhost ~]# netstat -tlunp
#列出系统中所有已经启动的服务(已经监听的端口),但不包含已经连接的网络服务
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:53575 0.0.0.0:*
LISTEN
1200/rpc.statd
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1181/rpcbind
tcp 0 0 0.0.0.0:22 O.O.O.O:* LISTEN 1405/sshd
tcp 0 0127.0.0.1:631 O.O.O.O:* LISTEN 1287/cupsd
tcp 0 0 127.0.0.1:25 O.O.O.O:* LISTEN 1481/master
tcp 0 0 :::57454 :::* LISTEN 1200/rpc.statd
tcp 0 0 :::111 :::* LISTEN 1181/rpcbind
tcp 0 0 :::22 :::* LISTEN 1405/sshd
tcp 0 0 ::1:631 :::* LISTEN 1287/cupsd
tcp 0 0 ::1:25 :::* LISTEN 1481/master
udp 0 0 0.0.0.0:58322 0.0.0.0:* 1276/avahi-daemon
udp 0 0 0.0.0.0:5353 O.O.O.O:* 1276/avahi-daemon
udp 0 0 0.0.0.0:111 O.O.O.O:* 1181/rpcbind
udp 0 0 0.0.0.0:631 O.O.O.O:* 1287/cupsd
udp 0 0 0.0.0.0:56459 0.0.0.0:* 1200/rpc.statd
udp 0 0 0.0.0.0:932 O.O.O.O:* 1181/rpcbind
udp 0 0 0.0.0.0:952 O.O.O.O:* 1200/rpc.statd
udp 0 0 :::111 :::* 1181/rpcbind
udp 0 0 :::47858 :::* 1200/rpc.statd
udp 0 0 :::932 :::* 1181/rpcbind

执行这条命令会看到服务器上所有已经开启的端口,也就是说,通过这些端口就可以知道当前服务器上开启了哪些服务。

解释一下命令的执行结果:
  • Proto:数据包的协议。分为 TCP 和 UDP 数据包;
  • Recv-Q:表示收到的数据已经在本地接收缓冲,但是还没有被进程取走的数据包数量;
  • Send-Q:对方没有收到的数据包数量;或者没有 Ack 回复的,还在本地缓冲区的数据包数量;
  • Local Address:本地 IP : 端口。通过端口可以知道本机开启了哪些服务;
  • Foreign Address:远程主机:端口。也就是远程是哪个 IP、使用哪个端口连接到本机。由于这条命令只能查看监听端口,所以没有 IP 连接到到本机;
  • State:连接状态。主要有已经建立连接(ESTABLISED)和监听(LISTEN)两种状态,当前只能查看监听状态;
  • PID/Program name:进程 ID 和进程命令;

再举个例子:

[root@localhost ~]# netstat -an
#查看所有的网络连接,包括已连接的网络服务、监听的网络服务和Socket套接字
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:53575 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 192.168.0.210:22 192.168.0.105:4868 ESTABLISHED
tcp 0 0 :::57454 :::* LISTEN
...省略部分输出...
udp 0 0 :::932 :::*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
#Socket套接字输出,后面有具体介绍
Unix 2 [ ACC ] STREAM LISTENING 11712 /var/run/dbus/system_bus_socket
unix 2 [ ACC ] STREAM LISTENING 8450 @/com/ubuntu/upstart unix 7. [ ] DGRAM 8651 @/org/kernel/udev/udevd
unix 2 [ ACC ] STREAM LISTENING 11942 @/var/run/hald/dbus-b4QVLkivf1
...省略部分输出...

执行"netstat -an"命令能査看更多的信息,在 Stated 中也看到了已经建立的连接(ESTABLISED)。这是 ssh 远程管理命令产生的连接,ssh 对应的端口是 22。

而且我们还看到了 Socket 套接字。在服务器上,除网络服务可以绑定端口,用端口来接收客户端的请求数据外,系统中的网络程序或我们自己开发的网络程序也可以绑定端口,用端口来接收客户端的请求数据。这些网络程序就是通过 Socket 套接字来绑定端口的。也就是说,网络服务或网络程序要想在网络中传递数据,必须利用 Socke 套接字绑定端口,并进行数据传递。

使用"netstat -an"命令查看到的这些 Socke 套接字虽然不是网络服务,但是同样会占用端口,并在网络中传递数据。

解释一下 Socket 套接字的输出:
  • Proto:协议,一般是unix;
  • RefCnt:连接到此Socket的进程数量;
  • Flags:连接标识;
  • Type:Socket访问类型;
  • State:状态,LISTENING表示监听,CONNECTED表示已经建立连接;
  • I-Node:程序文件的 i 节点号;
  • Path:Socke程序的路径,或者相关数据的输出路径;