失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 无公网IP VB应用从外网访问内网服务器

无公网IP VB应用从外网访问内网服务器

时间:2023-02-02 17:05:16

相关推荐

无公网IP VB应用从外网访问内网服务器

应用需求

之前做的板子加密工具,需要客户在工厂将所有板子先扫描一遍,然后将扫描得到的结果文件通过邮件发送给开发人员。开发人员根据收到的数据文件,生成一个加密文件,并发回给工厂。工厂收到加密数据后,需要重新扫描所有板子,将加密数据写入对应的板子。这样做的结果是需要工厂对所有板子操作两遍,中间还需要等待接收邮件,比较麻烦和费时。

新的设想是,工厂在扫描每片板子时,即时通过互联网将数据发送到开发人员架设的服务器,服务器收到数据后,对数据进行加密后回传。扫描工具得到回传数据后,立即将加密数据烧入板子,完成对板子的加密。

这样做的好处是,工厂只需要对所有板子操作一遍即可。虽然其中也有收发数据,但是收发数据完全是自动的,对操作人员来说,就像没有发生一样。操作人员只需要将串口连接上板子,在工具上点击一次加密即可,几秒钟就可以完成一片板子的加密。这样就比较简单了。

软件编写

工具软件采用VB编写,工厂端的软件为客户端,开发端的软件为服务器。因条件所限,开发端的服务器处在内网中(移动光宽带),出口无公网IP。

1、服务器编写简述:

新建一个VB工程,添加 Microsoft Winsock Control6.0 部件。添加该部件后,就可以在窗体上添加一个Winsock控件,命名为sckServer。在窗体load时,需要设置本地端口号(用于监听客户端的连接请求),然后启用端口监听。代码如下:

Private Sub Form_Load()

intMax = 0

sckServer(0).LocalPort = 12345

txtServerIP.Text =sckServer(0).LocalIP ‘仅用于显示本地IP,如192.168.100.22

sckServer(0).Listen

End Sub

当客户端发起连接请求后,服务器端会产生_ConnectionRequest事件。在该事件中可以处理接受连接请求:

Private Sub sckServer_ConnectionRequest(Index As Integer, ByValrequestID As Long)

If Index = 0 Then

intMax = intMax + 1

Load sckServer(intMax)

sckServer(intMax).LocalPort= 0

sckServer(intMax).AcceptrequestID

End If

End Sub

一旦客户端和服务器端建立连接后,客户端发送数据后,服务器端会产生_DataArrival事件,服务器端可以在这里检查数据是否合法,并对数据加密后回传给客户端。

Private Sub sckServer_DataArrival(Index As Integer, ByVal bytesTotalAs Long)

Dim MyStr As String

sckServer(Index).GetData MyStr

If Check(MyStr) =True Then

Process(MyStr)

sckServer(Index).SendData MyStr ‘回传加密后的数据

End If

End Sub

1、客户端编写简述:

同样,新建一个VB工程,添加Microsoft Winsock Control6.0 部件。添加该部件后,在窗体上添加一个Winsock控件,命名为WinsockClient。窗体上放置一个Command按钮,命名为cmdConnect,用于连接服务器。点击该按钮后,产生_Click事件,在其中处理连接过程:

Private Sub cmdConnect_Click()

Dim SendTime As Single,PreTime As Single

'Print txtServerIP.Text

WinsockClient.Close

‘需要先输入服务器地址,

If txtServerIP.Text = ""Then

'从外网:54333 通过nat123访问,映射到内网192.168.100.22:12345

WinsockClient.RemotePort= 54333

Else

WinsockClient.RemotePort = 12345'从局域网内访问,不需转换

End If

WinsockClient.RemoteHost = txtServerIP.Text

WinsockClient.Connect

NetStatus = False '置标志

SendTime =Timer() '取发送时刻

Do While Timer() <SendTime + 10 '最大等待10秒

If NetStatus =True Then

Exit Do

End If

DoEvents

Loop

'显示连接结果

If NetStatus = TrueThen

MsgBox "已连接到服务器", vbInformation

Else

WinsockClient.Close

MsgBox "连接服务器超时", vbInformation

End If

End Sub

在上面这个函数中,主要要给出客户端需要连接的服务器的IP地址和端口。如果客户端和服务器处在同一内网中,则只要将服务器的IP地址和监听的端口赋给客户端的remote属性即可,在内网中用例如下:

WinsockClient.RemotePort = 12345

WinsockClient.RemoteHost = 192.168.100.22

WinsockClient.Connect

如果客户端是外网连接服务器,则需要更改如下(以nat123穿透内网为例):

WinsockClient.RemotePort = 54333

WinsockClient.RemoteHost =

WinsockClient.Connect

这里 和 54333 是在nat123 上设置端口映射时,由nat123自动赋予的,不能随便更改。

当客户端调用WinsockClient.Connect后,服务器端就会产生sckServer_ConnectionRequest事件。然后服务器端调用sckServer(intMax).AcceptrequestID,接收连接请求,这时,客户端就会产生WinsockClient_Connect() 事件,表示连接成功。因此在该事件中,客户端可以设置连接成功标志。

Private Sub WinsockClient_Connect()

NetStatus = True

End Sub

以上代码在内网中测试没有问题。但是当客户端在外网中发起连接时,此时即使服务器端没有启动,在客户端仍会产生WinsockClient_Connect()事件。因为在外网情况下,客户端的数据是发往 nat123 服务器的,然后nat123 再将数据转发给内网的服务器。不管内网的服务器是否启动,正常情况下,客户端和nat123 之间的连接是成功的。如果nat123 到服务器的连接不通,则nat123会返回一些错误代码给客户端,所以从客户端来看,连接是成功的,并会接收到许多数据。

解决以上问题的方法是,在WinsockClient_Connect() 中不能立即判断为连接成功,而是发送一个特定的握手数据给服务器,服务器端收到握手数据后,立即返回一个特定的确认数据。当客户端收到确认数据后,才能确定连接是真正成功的。代码修改如下:

Private Sub WinsockClient_Connect()

'在这里发出一个握手信号给服务器

WinsockClient.SendData"发送指定字符串"

End Sub

在接收数据事件中判断回复数据:

Private Sub WinsockClient_DataArrival(ByVal bytesTotal As Long)

Dim MyStr As String

WinsockClient.GetDataMyStr

If MyStr = "回复指定字符串" Then

'连接后,收到服务器端发来的握手信号,才表示真的连接上了

NetStatus = True

Else

'检查数据是否有server签名,如果是,则当作正常的加密数据,写入板子

‘不是,则不必处理

End If

End Sub

内网测试:

软件写好后,首先在内网中测试:

首先启动服务器,等待客户端连接:

然后启动客户端:

点击“未连接”按钮后,可以看到连接成功。在输入框中输入字符”test”后,点击发送,可以看到服务器中显示接收到一样的字符串,并在前面添加“reply:” 后,再回传给客户端,客户端这边也有显示收到的回传数据。截图如下:

如上图表示,在内网中,客户端和服务器之间的连接、数据收发是成功的。

外网测试

内网测试成功后,就需要进行外网测试。

将客户端软件复制到另外一台电脑中,该电脑使用无线网卡,连接手机上的wifi热点上网,模拟外网的环境。

服务器仍然在内网中,通过移动提供的HG8245路由器连接移动光宽带。

在没有采用NAT123 之前,从网上找了许多外网访问内网的帖子看,在华为HG8245路由器的管理页面里也反复尝试了DMZ主机和端口映射,都没有成功,客户端始终不能连接到服务器。

另外用IP地址查询到本机IP地址和路由器上显示的IP地址也不一致,看了网帖,明白这个似乎是没有公网IP的,移动将路由器又映射了一次,IP地址查看到的是移动的公网IP,路由器上看到的相当于是内网IP。截图如下:

Nat123 安装和使用

折腾了几天没有结果,看到网帖上有用nat123 做内网端口映射的,于是上nat123 的官网上看了一下。

Nat123 官网:/

首先要注册,截图如下:

然后下载windows版整合运行环境安装包/Pages_2_32.jsp

下载的安装包名为nat123_V1.160421_NET4.zip,在内网服务器所在电脑里解压后安装,需要好几分钟。

运行nat123的客户端,界面是这样的:

注意,没有添加映射之前,图中是没有那个蝴蝶图案的。

登录后,点击添加映射,按下图设置后,点击保存即可:

在这里,充值8元钱,完成实名认证后,才可以保存。保存后系统就不断刷新,直到出现前图中的彩色蝴蝶,就表示映射成功了。

映射成功后,启动服务器。在另一台模拟外网的电脑上运行客户端,点击连接测试,发现可以连接到服务器了。截图如下:

如果觉得《无公网IP VB应用从外网访问内网服务器》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。