应用需求
之前做的板子加密工具,需要客户在工厂将所有板子先扫描一遍,然后将扫描得到的结果文件通过邮件发送给开发人员。开发人员根据收到的数据文件,生成一个加密文件,并发回给工厂。工厂收到加密数据后,需要重新扫描所有板子,将加密数据写入对应的板子。这样做的结果是需要工厂对所有板子操作两遍,中间还需要等待接收邮件,比较麻烦和费时。
新的设想是,工厂在扫描每片板子时,即时通过互联网将数据发送到开发人员架设的服务器,服务器收到数据后,对数据进行加密后回传。扫描工具得到回传数据后,立即将加密数据烧入板子,完成对板子的加密。
这样做的好处是,工厂只需要对所有板子操作一遍即可。虽然其中也有收发数据,但是收发数据完全是自动的,对操作人员来说,就像没有发生一样。操作人员只需要将串口连接上板子,在工具上点击一次加密即可,几秒钟就可以完成一片板子的加密。这样就比较简单了。
软件编写
工具软件采用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应用从外网访问内网服务器》对你有帮助,请点赞、收藏,并留下你的观点哦!