在研究计算机网络作为课程主题时,我的概念是操作系统根据目标端口区分数据包并将其传递给在该端口上运行的应用程序。
后来我才知道我们可以使用同一个源(SourceIP:SourcePort)连接到两个不同的目的地(DestinationIP:DestinationPort)。
tcp 0 0 192.168.1.5:60000 199.7.57.72:80 ESTABLISHED 1000 196102 10179/firefox
tcp 0 0 192.168.1.5:60000 69.192.3.67:443 ESTABLISHED 1000 200361 10179/firefox
tcp 0 0 192.168.1.5:60000 69.171.234.18:80 ESTABLISHED 1000 196107 10179/firefox
tcp 0 0 192.168.1.5:60000 107.21.19.182:22 ESTABLISHED 1000 196399 10722/ssh
tcp 0 0 192.168.1.5:60000 69.171.234.18:443 ESTABLISHED 1000 201792 10179/firefox
tcp 0 0 192.168.1.5:60000 69.192.3.34:443 ESTABLISHED 1000 200349 10179/firefox
tcp 0 0 127.0.0.1:4369 127.0.0.1:51889 ESTABLISHED 129 12036 1649/epmd
tcp 0 0 192.168.1.5:60000 69.192.3.58:443 ESTABLISHED 1000 200352 10179/firefox
tcp 0 0 192.168.1.5:60000 74.125.236.88:80 ESTABLISHED 1000 200143 10179/firefox
tcp 0 0 192.168.1.5:60000 174.122.92.78:80 ESTABLISHED 1000 202935 10500/telnet
tcp 0 0 192.168.1.5:60000 74.125.236.87:80 ESTABLISHED 1000 201600 10179/firefox
再深入一点,我开始知道如果应用程序使用 bind() 系统调用将套接字描述符与特定的 IP 和端口组合绑定,那么我们就不能再次使用相同的端口。否则,如果端口未绑定到任何套接字描述符,我们可以再次使用相同的端口和 IP 组合连接到不同的目标。
我在 bind() 系统调用的手册页中读到
bind() assigns the address specified to by addr to the socket referred to by the file descriptor sockfd.
我的问题是:
当我们在编写客户端程序时通常不调用 bind() 系统调用时,操作系统如何自动选择端口号。
当两个不同的应用程序使用相同的端口和 IP 组合连接到两个不同的服务器时,当这些服务器回复时,操作系统如何找出需要将哪个数据包重定向到哪个应用程序。