计算机网络——在路由器设置NAT的情况下实现主机之间的通信
我在学习计算机网络的时候发现很多主机的IP地址都是192.168.0.0/24格式的,这让我感到疑惑,难道两台计算机会具有相同的IP地址吗?随着学习的深入,我才发现是因为引入NAT(Network Address Translation)机制,有关NAT的知识可以参考博文 https://www.cnblogs.com/dongzhuangdian/p/5105844.html ,这里我不多做赘述。
NAT机制虽然能扩大IP的地址范围,但也有个缺点,就是会屏蔽内网的主机,你无法通过公有网络直接访问到内网的某台计算机。
要想实现访问内网的某台计算机,你必须能够设置连接内网路由器的NAT表。
1.查询计算机IP设置
查看该表可以发现,主机的网络关口(默认网关)是 192.168.0.1 ,私有IP是192.168.0.101
然后我们在浏览器中输入网络关口IP地址192.168.0.1,可以看到下面的信息
WAN口状态指示的是外网的IP信息,而LAN口状态指示的当前内网的IP信息。
我们可以看到,我们当前内网在因特网中是以IP 58.198.64.221 地址存在的,这个IP就是公有IP。
2.设置NAT表
通过以上的设置之后,如果从外网发来的报文,请求报文的目的端口号是65400的话,那么这个报文就会被送向内网IP 192.168.0.101 这个主机的12300端口。这个主机就是我们当前的主机。
3.设置服务器主机
我在台式机上运行如下python代码:
from socket import *
serverPort = 12300
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', serverPort))
print('The server is ready')
while True:
recivedMessage, clientAddress = serverSocket.recvfrom(2048)
print('接收到: ' + recivedMessage.decode())
print(clientAddress)
message = 'OK!'
serverSocket.sendto(message.encode(),clientAddress)
这里我用的UDP协议,用TCP也是一样的。我让这个进程作为服务器,打开端口12300,然后监听网络数据,显示收到的数据和发送方的地址信息,然后反馈信息“OK!”给发送方。运行该脚本,显示如下信息:
4.设置客户机
在另一台电脑上运行如下python代码:
from socket import *
serverName = '58.198.64.221'
serverPort = 65400
clientPort = 5488
clientSocket = socket(AF_INET, SOCK_DGRAM)
clientSocket.bind(('', clientPort))
while True:
message = input('INPUT A SENTENCE:')
clientSocket.sendto(message.encode(),(serverName, serverPort))
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print(modifiedMessage.decode())
print(serverAddress)
clientSocket.close()
这里我用自己的笔记本电脑作为客户机访问台式机,观察上述代码,我们设置服务器的IP地址为58.198.64.221,也就是台式机的外网IP,然后端口号为65400。因为我们已经通过路由器设置NAT表,所以送往 58.198.64.211:65400的报文就会被送到 192.168.0.101:12300 。也就是我们台式机的服务器端口。我们设置客户机的套接字端口为5488,用来测试回显。这个脚本会不断向服务器(台式机)发送网络,然后接受服务器的反馈信息,并显示反馈信息。
运行客户机脚步,并输入一些信息:
我们在脚本中输入:hello! 你好呀
发现反馈了如下信息:
OK!
{‘58.198.64.221’, 65400}
说明服务器已经接受到了客户机发送的信息,并显示了我们之前设置的反馈信息OK!,以及服务器的IP信息。
我们观察服务器终端,可以看到如下信息:
服务器,也就是我们的台式机成功接收到了信息,并显示了接收信息hello!你好呀,而且我们观察IP地址信息可以看到,信息来自于 58.198.64.221:5488 。因为我的笔记本用无线网接入的是和台式机相同的网络,所以显示的IP地址也是58.198.64.221,然后端口号就是我们之前在客户机脚本中设置的5488 。
这说明我们成功实现了两台主机通过因特网进行信息交互!
想想当时还是有点小激动的。
因为是相同的IP,所以相当于客户机的报文在因特网中转了一圈又回到了原来发送的路由器,但路由器并不会记得这是不是之前发出的报文。