网管小贾 / sysadm.cc
各位爱好 VB 的小伙伴们,大家好!
说起使用 VB 来编写各种小程序、小工具,一般情况下可以说是易如反掌、手到擒来,非常容易上手。
往窗体上拖几个按钮、文本框,不一会儿就能做个像模像样的小程序了,内心的成就感也得到了满足。
不过如果要让各位写一个 TCP/UDP 的网络通讯程序,可能 VB 就有点那个啥不太自信了。
呵呵,不是说 VB 写不了网络程序,写是也能写,不过通常的作法非常麻烦。
大部分的传统操作是,往窗体上拖几个 WinSock 控件,然后在 WinSock 的事件上写代码。
虽然这样做没什么问题,只是当客户端数量猛增时,我们就不得不同时增加 WinSock 控件的数量。
如果能猜出来有几个客户端还好说,要是猜不出来,那么就完蛋了!
总不能无限制地增加 WinSock 控件的数量吧?
于是有些聪明的小伙伴想出了一个好办法,那就是用数组,对,控件数组!
好家伙,这一个两个的还好对付,这一下子出来个数组,好像把事件搞得更加复杂了。
并且,也没有摆脱对控件的依赖啊!
好了,啰嗦了这么多,其实这次是来给大家伙献宝贝的!
没错,你猜对了,接下来我就向小伙伴们介绍一个不用 WinSock 控件照样实现并且还更方便好用的 VB 编写网络通讯解决方案。
OK,让我们请出今天的主角:VbRichClient !
这个 VbRichClient 是国外一位大神使用 VB 开发的一个 VB 环境下的框架程序。
嗯嗯,你没眼花,他就是用 VB 写的哈!
这个框架程序可以实现很多超级牛叉的功能,包括图形、数据库等等,其中就有我们今天要讲的网络功能。
多说一句, VbRichClient 所包含的网络通讯功能不但稳定性较 WinSock 高,并且所需书写的代码量也非常少,最重要的是,我们不再需要拖放控件了!
(文末有源代码下载哦!)
更重要的是,对于未知数量的服务端或客户端,也只需要增加一些类似的代码而不需要再麻烦搞什么控件数组了。
好了,在正式开始之前,我们先简单复习一下 TCP/UDP 这两个好哥们的相关知识吧!
这两个哥们是常见的两种网络通讯协议,也可以说是方式,在这里我们说得简单一些,没必要长篇大论,只讲部分关键所涉及到后面程序的知识就行。
首先,我们来说一说 TCP 这位哥哥。
说到 TCP ,大家都知道三次握手,不过我们不讲什么晦涩的协议知识,只说它是怎么干活的。
通常 TCP 连接方式主要分为服务端和客户端两部分,一般情况下服务端是一个,而客户端则可以是多个,多个客户端去连接一个服务端,然后它们相互可以发送和接收数据。
建立 TCP 连接的做法是,客户端先发送一个信号给服务端,然后服务端接收到信号后回送信号给客户端,最后客户端收到服务端的回信后再发送一个信号给服务端。
有点像两个人打招呼哈,互相打完招呼后,服务端和客户端都已经确信对方在线,连接也就成功建立起来了。
由些可见, TCP 这位哥哥做事比较严谨,他是两点之间两头跑,必须跑到位,数据送到手里才算完成工作。
因此这种方式也被称为可靠连接,我们可以将这种方式想像成两个人打电话,因为它是点对点的通讯,通常信号传送不会丢失。
其次,我们再说一说 UDP 这位弟弟。
UDP 这位弟弟就不像它的哥哥那样严谨了,倒是有点像寄送快递,快递现在在哪儿,什么时候送到是一概不关心,发信方离开手就不管了。
当一台电脑发送(广播)信号出去后,这个信号就会被一个网络中的其他所有电脑接收到,而只有真正需要这个信号数据的电脑才会真正的接收到,其他电脑会忽略丢弃信号。
看这不靠谱的样子, UDP 有时也被称为不可靠连接,因为它并没有真正的与其他通讯对象建立连接,而且所发送出去的信号数据也存在不可达( NAT 等)或中途丢失的风险。
虽然 UDP 看上去工作得不咋地,其实它也是有些用场的,比如在无法明确建立点对点连接的前提下(可能一开始要找谁发信方自己的不清楚),又比如一对多或多对多的通讯时,UDP 就可以施展拳脚了。
有了前面的基础知识,我们运用 VbRichClient 也就更加容易一些了。
VbRichClient 实际使用的是 RC6.dll 动态链接库文件,因此在 VB 中将其引入。
网络上绝大多数内容都说的是 RC5 ,我这儿只讲最新版的 RC6 ,比旧版代码要改进许多,也更适合更新版的操作系统。
先来介绍一下 VbRichClient 实现 TCP 通讯的方法。
找三台电脑,一台做服务器,另两台做客户端。
当然,服务端和客户端不仅限于这些数量以及系统版本。
1、点击 TCP Bind 按钮,服务端绑定 IP 和端口在 0.0.0.0:35353 上并启动侦听,等待客户端连接。
当然,你也可以绑定 192.168.1.66 这个本地 IP 地址,只不过只能是同网段的本地客户端才可以连接了。
2、在两个客户端分别指定服务端的 IP 地址和侦听端口,然后点击 TCP Bind 绑定。
3、在客户端一侧点击连接 TCP Connect... 按钮来连接服务端,在服务端接收到连接请求的同时,客户端也各自获取到了连接句柄。
4、连接已经建立,这个时候我们就可以用客户端向服务端发送信息了。
比如从两个客户端分别发送以下信息到服务端。
# 客户端一(192.168.1.88) => 服务端(192.168.1.66)
“大哥,俺是关羽,今天几点做核酸啊?”
# 客户端二(192.168.1.88) => 服务端(192.168.1.66)
“大哥,俺是张飞,听说今天做核酸换地方了?”
5、不仅如此,服务端也可以发送信息给客户端。
不过注意这里有些讲究,服务端要先指定客户端,然后才能发送,一次一个。
(网上流行的一些代码并没有这个方法的具体实现内容。)
比如,从服务端分别回复发送如下信息到两个客户端上。
# 服务端(192.168.1.66) => 客户端一(192.168.1.88)
“云长,还是老时间,不过今天10点半就结束,你得抓点紧!”
# 服务端(192.168.1.66) => 客户端二(192.168.1.99)
“翼德,还是老地方,不过今天10点半就结束,你得抓点紧!”
6、客户端和服务端通讯很愉快,为了下次能安全连接,标准做法就是在最后要优雅地断开连接。
在客户端一侧点击断开连接 TCP Disconnect... 按钮即可结束连接,服务端也正常获取到对应客户端的断开信息。
整个一套下来如行云流水,极度完美啊!
有兴趣的小伙伴还可以多打开一些客户端试试。
看完了 TCP 的实现方法,接下来我们再看看 VbRichClient 是如何实现 UDP 的通讯。
UDP 的特点是,各端点绑定各自的本地 IP 地址和端口以及远程 IP 地址和端口。
我们在这儿举个例子,将端点 A分别与端点 B和端点 C绑定。
通过这样的设定,端点 A 就可以和端点 B 或端点 C对话了,但请注意它们之间的关系没有谁是主谁是辅。
当然了,要说清楚,你想和谁对话,那么远程 IP 就指定谁,只绑定,不需要刻意建立连接。
绑定好以后,我们就可以发消息了。
# 端点A(192.168.1.66) => 端点B(192.168.1.88)
“云长,你来了没?”
如果你想换个端点发送消息,那么远程改成新对象即可。
# 端点A(192.168.1.66) => 端点C(192.168.1.99)
“翼德,你来了没?”
反过来也是一样的,只要绑定自己和对方的 IP 和端口,你就可以随意发送消息。
# 端点B(192.168.1.88) => 端点A(192.168.1.66)
“大哥,我已经排上了,好像三弟还没来啊!”
# 端点C(192.168.1.99) => 端点A(192.168.1.66)
“大哥,我刚打疫苗去了,马上到哈!”
# 端点A(192.168.1.66) => 端点C(192.168.1.99)
“我去!你傻啊!他喵的打完疫苗48小时之内不能做核酸!”
# 端点C(192.168.1.99) => 端点B(192.168.1.88)
“二哥,你不是说没事嘛!那...现在咋办啊?”
可以看得出,发送消息自由切换,并不拘泥于建立什么连接,非常方便灵活。
网络上并没有完整版的 VbRichClient 源代码,我是经过一番调试研究,最终获得成功的。
本源代码不仅可以实现基本的通讯功能,而且还可以在此基础上补充了更多的代码写法,可以实现更多的服务端和客户端的通讯功能。
另外,我将 TCP/UDP 两部分实现代码都放在一套源代码中,代码注释写得很清楚,调试起来也很方便。
联系客服