如何在公司访问家里的电脑

因为IPv4地址有限,最大42亿个。为了更好的利用这有限的IP数量,网络分为局域网和广域网,将IP分为了私有IP和公网IP,一个局域网里的N多台机器都可以共用一个公网IP,从而大大增加了"可用IP数量"。

当我们需要发送网络包的时候,在IP层,需要填入源IP地址,和目的IP地址,也就是对应快递的发货地址和收货地址。

但是我们家里的局域网内,基本上都用192.168.xx.xx这样的私有IP

如果我们在发送网络包的时候,这么填。对方在回数据包的时候该怎么回?毕竟千家万户人用的都是192.168.0.1,网络怎么知道该发给谁?

所以肯定需要将这个192.168.xx私有IP转换成公有IP

因此在上篇文章最后,留了这么个问题。局域网内用的是私有IP,公网用的都是公有IP。一个局域网里的私有IP想访问局域网外的公有IP,必然要做个IP转换,这是在哪里做的转换呢?

答案是NAT设备,全称Network Address Translation,网络地址转换。基本上家用路由器都支持这功能。

我们来聊下它是怎么工作的:

NAT的工作原理

为了简单,我们假设你很富,你家里分到了一个公网IP地址 20.20.20.20,对应配到了你家自带NAT功能的家用路由器上,你家里需要上网的设备有很多,比如你的手机,电脑都需要上网,他们构成了一个局域网,用的都是私有IP,比如192.168.xx。其中你在电脑上执行ifconfig命令,发现家里的电脑IP是192.168.30.5。 你要访问的公网IP地址是30.30.30.30。

于是就有下面这样一张图

当你准备发送数据包的时候,你的电脑内核协议栈就会构造一个IP数据包。这个IP数据包报头里的发送端IP地址填的就是192.168.30.5,接收端IP地址就是30.30.30.30。将数据包发到NAT路由器中。

此时NAT路由器会将IP数据包里的源IP地址修改一下,私有IP地址192.168.30.5改写为公网IP地址20.20.20.20,这叫SNATSource Network Address Translation,源地址转换)。并且还会在NAT路由器内部留下一条 192.168.30.5 -> 20.20.20.20的映射记录,这个信息会在后面用到。之后IP数据包经过公网里各个路由器的转发,发到了接收端30.30.30.30,到这里发送流程结束。

如果接收端处理完数据了,需要发一个响应给你的电脑,那就需要将发送端IP地址填上自己的30.30.30.30,将接收端地址填为你的公网IP地址20.20.20.20,发往NAT路由器。NAT路由器收到公网来的消息之后,会检查下自己之前留下的映射信息,发现之前留下了这么一条 192.168.30.5 -> 20.20.20.20记录,就会将这个数据包的目的IP地址修改一下,变成内网IP地址192.168.30.5, 这也叫DNAT(Destination Network Address Translation,目的地址转换)。 之后将其转发给你的电脑上。

整个过程下来,NAT悄悄的改了IP数据包的发送和接收端IP地址,但对真正的发送方和接收方来说,他们却对这件事情,一无所知

这就是NAT的工作原理。

NAPT的原理

到这里,相信大家都有一个很大的疑问。

局域网里并不只有一台机器,局域网内每台机器都在NAT下留下的映射信息都会是 192.168.xx.xx -> 20.20.20.20,发送消息是没啥事,但接收消息的时候就不知道该回给谁了。

这问题相当致命,因此实际上大部分时候不会使用普通的NAT

那怎么办呢?

问题出在我们没办法区分内网里的多个网络连接。

于是乎:

我们可以加入其他信息去区分内网里的各个网络连接,很自然就能想到端口。

但IP数据包(网络层)本身是没有端口信息的。常见的传输层协议TCP和UDP数据报文里才有端口的信息。

于是流程就变成了下面这样子:

当你准备发送数据包的时候,你的电脑内核协议栈就会先构造一个TCP或者UDP数据报头,里面写入端口号,比如发送端口是5000,接收端口是3000,然后在这个基础上,加入IP数据报头,填入发送端和接收端的IP地址。

那数据包长这样。

假设,发送端IP地址填的就是192.168.30.5,接收端IP地址就是30.30.30.30。

将数据包发到NAT路由器中。

此时NAT路由器会将IP数据包里的源IP地址和端口号修改一下,从192.168.30.5:5000改写成20.20.20.20:6000。并且还会在NAT路由器内部留下一条 192.168.30.5:5000 -> 20.20.20.20:6000的映射记录。之后数据包经过公网里各个路由器的转发,发到了接收端30.30.30.30:3000,到这里发送流程结束。

接收端响应时,就会在数据包里填入发送端地址是30.30.30.30:3000,将接收端是20.20.20.20:6000,发往NAT路由器。NAT路由器发现下自己之前留下过这么一条 192.168.30.5:5000 -> 20.20.20.20:6000的记录,就会将这个数据包的目的IP地址和端口修改一下,变回原来的192.168.30.5:5000。 之后将其转发给你的电脑上。

如果局域网内有多个设备,他们就会映射到不同的公网端口上,毕竟端口最大可达65535,完全够用。这样大家都可以相安无事。

像这种同时转换IP和端口的技术,就是NAPT(Network Address Port Transfer , 网络地址端口转换 )。

看到这里,问题就来了。

那这么说只有用到端口的网络协议才能被NAT识别出来并转发?

但这怎么解释ping命令?ping基于ICMP协议,而ICMP协议报文里并不带端口信息。我依然可以正常的ping通公网机器并收到回包。

事实上针对ICMP协议,NAT路由器做了特殊处理。ping报文头里有个Identifier的信息,它其实指的是放出ping命令的进程id

对NAT路由器来说,这个Identifier的作用就跟端口一样。

另外,当我们去抓包的时候,就会发现有两个Identifier,一个后面带个BE(Big Endian),另一个带个LE(Little Endian)。

其实他们都是同一个数值,只不过大小端不同,读出来的值不一样。就好像同样的数字345,反着读就成了543。这是为了兼容不同操作系统(比如linux和Windows)下大小端不同的情况。

内网穿透是什么

看到这里,我们大概也发现了。使用了NAT上网的话,前提得内网机器主动请求公网IP,这样NAT才能将内网的IP端口转成外网IP端口

反过来公网的机器想主动请求内网机器,就会被拦在NAT路由器上,此时由于NAT路由器并没有任何相关的IP端口的映射记录,因此也就不会转发数据给内网里的任何一台机器。

举个现实中的场景就是,你在你家里的电脑上启动了一个HTTP服务,地址是192.168.30.5:5000,此时你在公司办公室里想通过手机去访问一下,却发现访问不了。

那问题就来了,有没有办法让外网机器访问到内网的服务?

有。

大家应该听过一句话叫,"没有什么是加中间层不能解决的,如果有,那就再加一层"。

放在这里,依然适用。

说到底,因为NAT的存在,我们只能从内网主动发起连接,否则NAT设备不会记录相应的映射关系,没有映射关系也就不能转发数据。

所以我们就在公网上加一台服务器x,并暴露一个访问域名,再让内网的服务主动连接服务器x,这样NAT路由器上就有对应的映射关系。接着,所有人都去访问服务器x,服务器x将数据转发给内网机器,再原路返回响应,这样数据就都通了。这就是所谓的内网穿透

像上面提到的服务器x,你也不需要自己去搭,已经有很多现成的方案,花钱就完事了,比如花某壳。

到这里,我们就可以回答文章标题的问题。

为什么我在公司里访问不了家里的电脑?

那是因为家里的电脑在局域网内,局域网和广域网之间有个NAT路由器。由于NAT路由器的存在,外网服务无法主动连通局域网内的电脑。

两个内网的聊天软件如何建立通讯

好了,问题就叒来了。

我家机子是在我们小区的局域网里,班花家的机子也是在她们小区的局域网里。都在局域网里,且NAT只能从内网连到外网,那我电脑上登录的QQ是怎么和班花电脑里的QQ连上的呢?

上面这个问法其实是存在个误解,误以为两个qq客户端应用是直接建立连接的。

然而实际上并不是,两个qq客户端之间还隔了一个服务器。

也就是说,两个在内网的客户端登录qq时都会主动向公网的聊天服务器建立连接,这时两方的NAT路由器中都会记录有相应的映射关系。当在其中一个qq上发送消息时,数据会先到服务器,再通过服务器转发到另外一个客户端上。反过来也一样,通过这个方式让两台内网的机子进行数据传输。

两个内网的应用如何直接建立连接

上面的情况,是两个客户端通过第三方服务器进行通讯,但有些场景就是要抛开第三端,直接进行两端通信,比如P2P下载,这种该怎么办呢?

这种情况下,其实也还是离不开第三方服务器的帮助。

假设还是A和B两个局域网内的机子,A内网对应的NAT设备叫NAT_A,B内网里的NAT设备叫NAT_B,和一个第三方服务器server。

流程如下:

step1和2: A主动去连server,此时A对应的NAT_A就会留下A的内网地址和外网地址的映射关系,server也拿到了A对应的外网IP地址和端口。

step3和4: B的操作和A一样,主动连第三方server,NAT_B内留下B的内网地址和外网地址的映射关系,然后server也拿到了B对应的外网IP地址和端口。

step5和step6以及step7: 重点来了。此时server发消息给A,让A主动发UDP消息到B的外网IP地址和端口。此时NAT_B收到这个A的UDP数据包时,这时候根据NAT_B的设置不同,导致这时候有可能NAT_B能直接转发数据到B,那此时A和B就通了。但也有可能不通,直接丢包,不过丢包没关系,这个操作的目的是给NAT_A上留下有关B的映射关系

step8和step9以及step10: 跟step5一样熟悉的配方,此时server再发消息给B,让B主动发UDP消息到A的外网IP地址和端口。NAT_B上也留下了关于A到映射关系,这时候由于之前NAT_A上有过关于B的映射关系,此时NAT_A就能正常接受B的数据包,并将其转发给A。到这里A和B就能正常进行数据通信了。这就是所谓的NAT打洞

step11: 注意,之前我们都是用的UDP数据包,目的只是为了在两个局域网的NAT上打个洞出来,实际上大部分应用用的都是TCP连接,所以,这时候我们还需要在A主动向B发起TCP连接。到此,我们就完成了两端之间的通信。

这里估计大家会有疑惑。

端口已经被udp用过了,TCP再用,那岂不是端口重复占用(address already in use)?

其实并不会,端口重复占用的报错常见于两个TCP连接在不使用SO_REUSEADDR的情况下,重复使用了某个IP端口。而UDP和TCP之间却不会报这个错。之所以会有这个错,主要是因为在一个linux内核中,内核收到网络数据时,会通过五元组(传输协议,源IP,目的IP,源端口,目的端口)去唯一确定数据接受者。当五元组都一模一样的时候,内核就不知道该把数据发给谁。而UDP和TCP之间"传输协议"不同,因此五元组也不同,所以也就不会有上面的问题。

NAPT还分为好多种类型,上面的nat打洞方案,都能成功吗?

关于NAPT,确实还细分为好几种类型,比如完全锥形NAT和限制型NAT啥的,但这并不是本文的重点。所以我就略过了。我们现在常见的都是锥形NAT。上面的打洞方案适用于大部分场景,这其中包括限制最多的端口受限锥形NAT

总结

  • IPV4地址有限,但通过NAT路由器,可以使得整个内网N多台机器,对外只使用一个公网IP,大大节省了IP资源。
  • 内网机子主动连接公网IP,中间的NAT会将内网机子的内网IP转换为公网IP,从而实现内网和外网的数据交互。
  • 普通的NAT技术,只会修改网络包中的发送端和接收端IP地址,当内网设备较多时,将有可能导致冲突。因此一般都会使用NAPT技术,同时修改发送端和接收端的IP地址和端口。
  • 由于NAT的存在,公网IP是无法访问内网服务的,但通过内网穿透技术,就可以让公网IP访问内网服务。一波操作下来,就可以在公司的网络里访问家里的电脑。

最后留个问题,有了NAT之后,原本并不富裕的IPv4地址突然就变得非常够用了。

那我们为什么还需要IPv6?

另外IPv6号称地址多到每粒沙子都能拥有自己的IP地址,那我们还需要NAT吗?

作者:小白debug
       链接:
       https://juejin.cn/post/7170850066473680927
       来源:稀土掘金

(0)

相关推荐

  • XP系统不能访问局域网其他电脑

    在XP系统组建局域网后,在工作站的"网上邻居"中查看服务器的名称,但双击后却不能看到共享内容,并提示"无权查看". 首先在工作站看到了服务器的名称,这代表了电脑 ...

  • 为什么我访问局域网其他电脑老是出现要输入密码的?

    这是因为要连接的电脑未设置来宾访问模式引起的.解决方法如下: 1,在要访问的电脑上点击开始,运行,输入"gpedit.msc",点击确定.打开本地组策略编辑器. 2,依次展开计算机 ...

  • 怎么查看有没有人从网络访问自己的电脑

    今天给大家介绍一下怎么查看有没有人从网络访问自己的电脑的具体操作步骤.1. 打开电脑,进入桌面,点击左下角的开始图标.2. 在打开菜单中,依次点击设置---控制面板选项,打开.3. 在打开的控制面板页 ...

  • win10电脑访问同一局域网电脑时需要输入密码怎么取消

    我们的win10电脑在访问同一局域网电脑时,会弹出输入账号和密码的提示,想要取消登录操作,该怎么操作呢?我们需要在被访问的电脑中进行设置,今天就跟大家介绍一下win10电脑访问同一局域网电脑时需要输入 ...

  • 如何解决Windows电脑无法访问局域网其他电脑问题

    现在大部分用户都在使用Windows电脑,有些人遇到了无法访问局域网其他电脑问题,想知道如何解决,接下来小编就给大家介绍一下具体的操作步骤.具体如下:1. 首先第一步按下[win+R]快捷键打开[运行 ...

  • 如何设置可以让访问局域网的电脑不需要密码

    今天给大家介绍一下如何设置可以让访问局域网的电脑不需要密码的具体操作步骤.1. 首先打开电脑,找到桌面上的计算机图标,右键,在打开的菜单中,选择[管理]选项2. 进入计算机管理页面后,依次单击左侧的& ...

  • Win10无法访问网上邻居电脑共享的文件夹怎么办

    Windows10系统无法通过局域网访问网上邻居电脑共享的文件夹,出现这种情况怎么办呢?只需要经过几步简单的设置就可以了. 下面我们就来看看解决方法吧. 操作方法 01 在Windows10系统右键点 ...

  • 如何用手机访问QQ空间电脑版

    一些网友用手机访问QQ空间要么使用手机版,要么使用触屏版,但是这两个版本都无法打开电脑版空间的应用,下面就有一种用手机访问QQ空间电脑版的办法. 操作方法 01 首先下载QQ浏览器,如果手机系统自带Q ...

  • 怎么在家里的电脑上唱歌卡拉OK

    现在人们越来越喜欢唱歌了,同学聚会尤其喜欢去唱卡拉OK.那么你知道如何在家里唱卡拉OK吗?今天小编我就来为大家解惑. 操作方法 01 先用电脑进入"酷我k歌" 02 在" ...

  • wifi不用电脑怎么设置路由器(家里没有电脑怎么设置路由器)

    导读:很多人都会有这样的情况,家里没有电脑,只有手机,想买个无线路由器,接一条外网来使用wifi,如何设置呢?按例,实际操作一回,高手请绕道,若喜欢了,敬请关注一下,不喜了,也勿喷,感谢.设备及环境: ...