VisualFreeBasic控件_Network 网络通信

2026-1-21 / 0 评论 / 63 阅读

实现 UDP 和 TCP 通信,用于写服务器和客户端,广域网和局域网通信。
本控件已经封装复杂的通信操作,让我们能简单的方便的使用通信。而且都提供了源码,可以打开控件工程查看那些复杂的封装代码。
本控件没有显示内容,只有事件和属性。

为了能顺利使用本控件,建议先恶补“ UDP和TCP”“广域网和局域网”的相关知识体系,本文档不再阐述这些基础知识。

获取本机IP

通信的首要条件,IP地址,这里的IP地址是局域网的IP

   print Network1.LocalIP

获取广域网IP

我们自己电脑是无法获知自己电脑广域网IP地址的,需要访问外网,外网反馈给我们IP地址才可以得知。此IP地址是由宽带服务商提供,而且是动态的,一天可能变好几次。已经有一些服务器提供这样的功能,只要访问它的域名,就返回我们的IP地址。

print Http_Get("http://ip.3322.net/")

UDP通信

  • 启动UDP接收
    首先,必须开启接收,就是让软件监听UDP
   Network1.UdpPort =999 '每台电脑有很多UDP通信,用此端口号区分,如同电话的分机号
   If Network1.UdpOpen() = 0 Then 
      Print "开启失败,请注意防火墙提示时,需要允许。或者端口号被占用"
   Else
      Print "开启成功"
   End If
  • 收到数据事件
    当其它电脑发来数据,就会触发事件
Sub Form1_Network1_UdpNewData(hWndForm As hWnd, nn As Network_Data)
   Print "接收数据,内容:" , nn.Dat '非文本数据不要打印
End Sub
  • 发送数据到目标IP(IP就是上面获取的IP地址,局域网IP和广域网IP都可以)
    其它电脑把数据发送到接收方
Network1.UdpPostData(IP地址,端口号,"要发送的数据")

端口号就是开启接收时,设置的号码。

  • 广域网互相通信(服务器电脑和家庭电脑通信)
    两台电脑都启动UDP接收,那么就可以实现相互通信了
    局域网时,双方都知道对方的IP和端口,互相发数据即可,要是广域网,2台电脑都有独立外网IP地址,也没问题,和局域网一样操作。
    要是2台电脑,全部是家庭电脑,就无法实现广域网通信。当1台电脑有独立IP(比方服务器),1台家庭电脑,先由家庭电脑发UDP数据给服务器电脑,服务器电脑收到后,可以直接返回数据发送给家庭电脑
Sub Form1_Network1_UdpNewData(hWndForm As hWnd, nn As Network_Data)
   Print "接收数据,内容:" , nn.Dat '非文本数据不要打印

  Network1.UdpPostData(nn.ip,nn.Port,"数据")   '发给家庭电脑数据
End Sub

此时的 nn.ip,nn.Port IP 和端口,端口是一个伪端口,和真实的家庭电脑中的端口会不同(具体原理我们不需要懂,好奇的可以网上搜索原理)。有网上教程说此为:打洞

  • 广域网互相通信(家庭电脑和家庭电脑通信)
    家庭电脑和家庭电脑通信,是无法直接广域通信的,因此我们必须有一个服务器电脑,实现中转
    上面服务器电脑收到 家庭电脑的 “IP和端口”伪数据,A家庭电脑和B家庭电脑,都发送数据到服务器电脑,然后由服务器电脑,把 AB家庭电脑“IP和伪端口”返回。那么A家知道B家,B家知道A家,AB两家就可以脱离服务,自己互相发数据了。但是家庭电脑随时可能会发生IP地址和端口改变,为了保持长久连接,就需要每隔一定时间,和服务器通信来更新AB家庭电脑“IP和伪端口”

TCP通信(获取网页代码)

网站都是使用TCP通信,要是获取网页代码,其实不需要本控件,直接一个函数搞定

print Http_Get("http://ip.3322.net/")

还有一个函数:Http_Post 可以向服务发送大量数据,比方上传文件等等。
其实这个一个基于 HTTP协议的 TCP 通信,HTTP协议已经被自动处理,而后面要说的,都是原始通信数据,包括HTTP协议部分。

TCP通信(服务端)

TCP需区分服务端和客户端,服务端,一般都用在服务器电脑上,就是有独立外网IP的电脑,假如是家用电脑,需要路由器设置端口转发,而且IP随时会变,需要路由器设置DDNS(花生壳之类的服务,以前有免费免流量,现在到处是收费限制流量)
只是在局域网中使用,使用局域网IP,那么直接上,没任何限制。
开启服务端

   Network1.TcpServerPort =999 '每台电脑有很多TCP通信,用此端口号区分,如同电话的分机号
   If Network1.TcpServerOpen() = 0 Then 
      Print "开启失败,请注意防火墙提示时,需要允许。或者端口号被占用"
   Else
      Print "开启成功"
   End If 

当客户端发送数据过来,触发事件

Sub Form1_Network1_TcpServerNewData(hWndForm As hWnd, nn As Network_Data)
   Print "服务端收到数据:" ,Len(nn.Dat) 
   '这里开始才正式处理数据---
   'Network1.TcpServerSend(nn.SOCKET,"返回给客户端数据,可以是任意数据,不单单是文本")
   'Network1.TcpServerCloseClient nn.SOCKET  '主动断开客户端连接,并非立即断开,控件会自动等返回给客户端数据发送完成后才会断开。
End Sub

还有 “客户端连接请求” 和 “客户端断开连接” 事件
基本流程是,客户端请求连接-->连接成功-->互相发数据(只要不断开,双方可以一直连接,可以互相发数据,也可以不发)-->断开连接(客户端主动断开和服务端主动断开)

TCP通信(客户端)

客户端,不管是家庭电脑,服务器电脑,都可以用。

  • 一次性连接
    就是连接服务端,发送数据,服务端返回数据,就断开连接,一次完成。
 返回数据 =  Network1.TcpClientSendGet( IP , 端口 ,  "发送数据" )

网站一般都是如此,比方要获取网页代码,下面例题就是获取网页代码的

   Dim 域名 As String= "www.baidu.com"
   Dim 路径 As String = "index.html"
   Dim http请求 As String '构造HTTP协议
   http请求 = "GET /" + 路径 + !" HTTP/1.1\r\n" + "Host: " + 域名 + !" \r\n" + _
      "Pragma: no-cache" + !"\r\n" + _
      "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34" + !"\r\n" + _
      "Referer: https://www.baidu.com/" + !"\r\n" + _
      "Connection: close"               + !"\r\n" + _
      "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6" + !"\r\n\r\n"
   Dim 网页 As String =  Network1.TcpClientSendGet( 域名 , 80 ,  http请求 )  '网站端口是 80 
  • 长时间连接通信
    服务端和客户端一直连接着,随时随地互相发数据(注意:服务端连接数量有限制,超过限制,新连接就无法连接了,具体多少请网上搜索)
    先启动客户端
Dim 域名 As String = "88.88.88.88" '可以是域名,可以是IP地址,要是域名,控件会自动转换成IP的。
Dim 端口 As Long   = 999           '服务端开发的端口
If Network1.TcpClientOpen(域名, 端口) =0  Then
   Print "TCP连接到服务失败,请检查!!"
End If

连接成功,向服务端发数据

Network1.TcpClientSend(“发数据”)

客户端收到服务端发来的数据,触发事件

Sub Form1_Network1_TcpClientNewData(hWndForm As hWnd, nn As Network_Data)
   Print "客户端收到数据:" ,nn.Dat '假如是文本,非文本不要打印
End Sub

通信协议

网络通信中,一台电脑到另一台电脑经过很多设备,存在很多不确定因素。
在UDP和TCP通信中,双方只是发送数据,系统则是以数据包的形式传送到其它电脑。但是会存在各种问题。

  • UDP 通信问题,只管发数据包,不管对方是否接收到,因此存在丢包问题,无法保障数据完整性,一般解决方法,制造一个协议,校对数据CRC值,不正确可以通知对方重新发送。
  • TCP 通信问题,虽然是安全通信,不会丢包,但存在粘包和拆包问题。
  • 拆包:发送数据大,系统会拆分成 N个小包,接收方,收到的是一个一个小包
  • 粘包:发送数据小,系统会把小的合成一个合适的包发送。接收方收到的可能是多个数据。
  • 你永远无法知道是接收到的数据,是拆包还是粘包?还无法确定数据是否全部接收,等了好久,也不知道对方网卡了还是太忙来不及发送。

因此,大家都各自创造了各自的协议来处理这些问题,比方网络游戏,各自保密还加密,网页则使用HTTP协议,可以网上搜索到,可以搜索HTTP协议,可以参考这些成熟的协议,来解决自己的问题。

协议,只存在你写的服务端和客户端软件中,没有固定方法。
我的做法是:发数据时,添加一个头标记,表示开始,然后头标记后面是长度

'发送方 -----------------
Dim 数据 As String = "要发送的内容"
Dim 长度 As Long = Len(数据) + 4 + 4
数据 = "<yf>" & MKL(长度) & 数据
'接收方 ----------------
Sub Form1_Network1_TcpServerNewData(hWndForm As hWnd ,nn As Network_Data) 'TCP服务器接收到新数据

   If Left(nn.dat ,4) <> "<yf>" Then 
      Network1.TcpServerCloseClient nn.SOCKET
      Return '自己创建协议头,不对就不处理。
   End If
   Dim 总长度 As Long = CVL(Mid(nn.Dat,5,4))
   If Len(nn.dat) < 总长度 Then '总长度=头部+数据
      nn.nLen = 总长度 '(根据自己搞的协议获取总长度赋值,然后 nn.Dat 就累积收到的数据)
      Return
   End If
   Dim bb As String =mid(nn.dat,9,总长度-8)
   bb 就是完整的数据

End Sub

以上简单的协议,仅供参考

评论一下?

OωO
取消