必威体育Betway必威体育官网
当前位置:首页 > IT技术

Socket编程之外网访问内网

时间:2019-09-14 04:12:41来源:IT技术作者:seo实验室小编阅读:60次「手机版」
 

外网访问内网

如何将自己编写的TCP的服务器软件放到外网上去呢?这样不论是在哪里用什么网络都可以访问自己在局域网里的服务器了。

首先大家想到的应该是路由器上作端口映射,即NAT(Network Address Translation),网络地址转换。

以装有NAT软件的路由器为例,局域网里的IP要想访问外网就必须经过NAT转换为外网IP,外网IP要想访问内网ip只能先访问到路由器,然后通过路由器的转发规则访问到内网IP。

如何设置路由转发?以校园宽带路由器CrazyBox为例:

1 打开浏览器键入地址:http://192.168.1.1进入路由器设置界面:

2打开工具下的UPNP设置界面:

以下是BC官方网站对UPnP的解释:

UPnP(Universal Plug and Play),通用即插即用,是一组协议的统称,不能简单理解为UPnP="自动端口映射"。在BitComet下载中,UPnP包含了2层意思:

1、对于一台内网电脑,BitComet的UPnP功能可以使网关或路由器的NAT模块做自动端口映射,将BitComet监听的端口从网关或路由器映射到内网电脑上。

2、网关或路由器的网络防火墙模块开始对Internet上其他电脑开放这个端口。

我服务器软件所在计算机的IP为192.168.1.159,其所用端口为8888,因此添加到第一条。下面说明一下几个栏目的含义:

备注:表明转发的作用或者意义。当然也可以随便起了,最好能让用户一眼就知道这个转发是干嘛用的。

外部端口:外网客户端访问到路由器的端口,可以随意设置,一般设置等于内网端口。一般路由器的wan地址都是公网地址,下面会讲。

内部端口:即服务器软件所用的端口。

画个图演示一下:

一般来说这样就OK了,在客户端程序中,要连接路由器的外网地址,如下所示(基于MFC):

if(!m_sock.Create())

{

AfxmessageBox("Create fail!");

return false;

}

if(!m_sock.Connect("路由器外网地址",外部端口))

{

Dword nERROR = GetLastError();

AfxMessageBox("Connect fail!");

return FALSE;

}

下面问题就出现了,测试时,客户端怎么连不上,nError值为10060或10061,

查找官方资料,该错误码原因:

10060:由于连接方在一段时间后没有正确答复或联机的主机没有反应,连接尝试失败。

10061:目标机器积极拒绝连接

经过检查和努力,发现不是代码问题,也不是网络的问题,而是电信宽带的问题。

以上程序我们都认为路由器的wan口地址都是公网地址,然而并不是,为了节省公网IP,电信宽带分给路由器的仍然是以个内网IP,已经被NAT过了,这样的话在路由器上的端口映射是没有用的,必须先电信那里映射。

怎么查看路由器wan口地址?怎么辨别该地址是不是wan口地址?

首先还以CrazyBox路由器为例,进入设置页面,打开状态下的总览,地址一项即为wan口地址:

辨别是否为公网地址这里提供两种办法:

1 打开浏览器,搜索IP,出现的即为自己的计算机的公网IP:

如果该IP与路由器设置页面的IP不一致,则说明路由器wan口地址不是公网IP。

2 打开浏览器搜索万网查询,点击万网获取本地公网地址,则会跳出一个页面:

如果出现两个IP,则说明路由器wan口地址不是公网IP。

那么这种情况下该怎么办的?申请公网IP是很贵的,下面推荐花生壳

的内网参透服务,利用花生壳提供的域名访问内网服务器。

花生壳内网参透服务的原理,图来源于网络:

官方解释:

传统的动态域名服务(DDNS)必须在公网IP地址环境下实现访问,但随着全球互联网的飞速发展,各个宽带运营商均出现IPv4地址资源枯竭的问题,于是一些宽带运营商开始分配给用户内网IP地址,使得一部分正在使用公网DDNS软件的用户无法正常访问。在此情况下,NAT-DDNS技术应运而生。

NAT-DDNS服务器上同时存在DDNS服务和NAT转换服务,内网服务器通过DDNS服务程序向NAT-DDNS服务器注册本机的域名及内网IP地址信息。来自外网的请求对此域名进行访问时,域名解析服务会将NAT-DDNS服务器的公网IP地址返回给请求方,请求方通过访问NAT转换服务程序,启动内外网NAT转换,从而完成动态映射,实现内网穿透访问。

下面开始吧!

1 首先登入花生壳,注册账号

2 选择内网参透服务,是要花6元钱的,可以做两个映射,下面就来配置:

域名和外部端口就选他默认的即可,完成后,他会给你分配一个随机端口,该端口在服务到期前是不可以更改的。

默认分配了35672端口,下面解析一下该域名的ip,该域名的IP每次开启服务都不同。点击域名列表选项,点击域名解析即可查看:

可以将该IP替换掉代码中的IP了,替换之后,再次测试,连接成功!

然而问题又来了,之前在局域网的时候,服务器能获取每一个客户端的IP和端口。一旦客户端到了外网,获取的ip都是服务器的ip,都是192.168.1.159,而端口却是变化的。服务器代码:

void CsocketL::OnAccept(int nErrorCode)

{

// TODO: Add your specialized code here and/or call the base class

CSocketC *p = new CSocketC;

if(!Accept(*p))

{

delete p;

return;

}

CString szIP;

   UINT    nPort;

   p->GetPeerName(szIP,nPort);

CServerDlg *pDlg = (CServerDlg *)AfxGetMainWnd();

pDlg->OnAccept(szIP,nPort);

AfxMessageBox(szIP);

CSocket::OnAccept(nErrorCode);

}

该如何解决?用抓包软件Wireshark抓一下试试:

现让客户端在内网连接服务器,不用花生壳:

可以从三次握手中清楚的看到,源端口1349,与服务器获取端口一直。目标端口8888,与程序设定一致。这种方式的连接是不经过路由器的,双方的IP和端口都很明朗。

下面看看在外网访问的抓包:

发现其过程大致如下:

在花生壳内部端口号变了,甚至最后访问的不是服务器的8888端口,而是另外一个随机端口x,实际测试中服务器获取的客户端端口号是x+1。这其中映射加穿透,我还没搞明白,总之,端口变了。

那么真实开发软件遇到这种情况就不能获取客户端端口吗?其实一般都将IP地址跟端口放在消息内容中传送,对方收到后再解析,由应用层协议完成,这样不管他中间过程多曲折,IP和端口都不会变。

至于花生壳中间的过程有待学习,待更。

相关阅读

如何理解内网和外网

如何理解内网和外网 写这篇博文的动力来自于,大狗问我什么是内网和外网(没错,我就是站在程序猿顶端的有女票的程序猿:p),一个惊讶,为什

华硕内网密码泄露 官方正积极调查所有系统

A5创业网(公众号:iadmin5)3月29日报道,一名信息安全研究员两个月前向华硕发出警告称,有华硕员工在GitHub代码库中错误地发布了密码。这

从Uber废除强制仲裁条款,看国内网约车如何监管?

A5创业网(公众号:iadmin5)5月16日报道:昨日,Uber成为美国第二家废除强制性仲裁条款的大型科技公司,允许性骚扰受害者采用公开起诉等手段

站内网张海宁谈:友情链接交换与链接交易问题

二、友情链接交易问题互联网已经衍变成了一个资源的市场,我们看到有一些上市公司和一些国内比较有影响力的公司都在涉足购买大量的

什么是内网穿透?

● 每周一言 由因推果易,由果推因难。 导语 有时候,我们在外想要访问家里主机的资料,要么由于主机处于家庭路由器下,是非公网IP,要

分享到:

栏目导航

推荐阅读

热门阅读