VB6 通过winsock控件数组实现客户端和服务器多对一通信

前端之家收集整理的这篇文章主要介绍了VB6 通过winsock控件数组实现客户端和服务器多对一通信前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

说明:我是在最近开发一个考试系统过程中搜索到上面文章的,它提供的思想非常实用。当然,这篇文章仅提供了一个基本思路,详细的实现在人民邮电出版社出版的《Visual Basic网络通信协议分析与应用实现》(汪晓平 钟军等编著)有更精彩的,在4.3《Winsock控件实现TCP聊天》一章,供开发者参考。

上面引用文章的原文如下:

使用winsock控件可以实现客户端和服务器间C/S结构的通信,如果把客户端和服务器放置于同一台电脑中,并且将客户端winsock的RemoteHost设置为本机IP,则可以实现客户端程序和服务端程序间的自由通信。在应用程序之间采用winsock通信比内存共享等方法更简单快捷,同时也更安全。

在客户端中添加一个窗体,拖拽一个winsock控件到该窗体上。


@H_403_16@Private@H_403_16@Sub@H_403_16@Form_Load()

  1. @H_403_16@Me@H_403_16@.Winsock1.RemoteHost="192.168.1.5"@H_403_16@

  2. @H_403_16@Me@H_403_16@.Winsock1.RemotePort=10002

  3. @H_403_16@Me@H_403_16@.Winsock1.Connect

  4. @H_403_16@End@H_403_16@Sub@H_403_16@

Private Sub Form_Load() Me.Winsock1.RemoteHost = "192.168.1.5" Me.Winsock1.RemotePort = 10002 Me.Winsock1.Connect End Sub


RemoteHost代表需要连接的远程服务器IP地址,局域网中的通信可以使用路由器分配的IP地址。

RemotePort代表端口号,服务器和客户端通过该端口进行连接。


@H_403_16@Private@H_403_16@Sub@H_403_16@Winsock1_DataArrival(ByVal@H_403_16@bytesTotalAs@H_403_16@Long@H_403_16@)

  1. @H_403_16@Dim@H_403_16@strGetAs@H_403_16@String@H_403_16@

  2. @H_403_16@

  3. @H_403_16@'接收字符串并写入Text1控件中@H_403_16@

  4. @H_403_16@Winsock1.GetDatastrGet

  5. @H_403_16@Text1.Text=strGet

  6. @H_403_16@End@H_403_16@Sub@H_403_16@

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim strGet As String '接收字符串并写入Text1控件中 Winsock1.GetData strGet Text1.Text = strGet End Sub

当客户端的winsock接收到服务器发送来的数据后会触发Winsock1_DataArrival事件,利用GetData方法可以将数据读取出来,一般来说将数据读取到byte()数组中是最好的,因为利用字节数组可以收发图片、音频等文件,本例中为了演示所以直接用一个字符串变量来读取数据了。


@H_403_16@Dim@H_403_16@strSetAs@H_403_16@String@H_403_16@

  1. @H_403_16@Winsock1.SendDatastrSet

Dim strSet As String Winsock1.SendData strSet

客户端向服务器发送数据可以用SendData方法,该方法同样可以发送字节数组,这里为了演示所以发送了个字符串。

服务器端为了能同时和很多个不同的客户端进行通信,所以需要采用winsock控件数组,在服务器窗体中拖拽一个winsock控件,将其名称更改为Listener,该控件用于接收客户端的连接请求。再拖拽一个winsock控件到窗体中,然后将其Index属性更改为0,0即代表该控件是一个控件数组,为了使用方便所以把控件名称更改为Sock,该控件数组用于动态的和不同的客户端通信。

在服务器端的窗口中写入如下代码


@H_403_16@Private@H_403_16@Sub@H_403_16@Form_Load()

  1. @H_403_16@LoadSock(0)

  2. @H_403_16@Listener.LocalPort=10002'端口号@H_403_16@

  3. @H_403_16@Listener.Listen'开始侦听@H_403_16@

  4. @H_403_16@End@H_403_16@Sub@H_403_16@

Private Sub Form_Load() Load Sock(0) Listener.LocalPort = 10002 '端口号 Listener.Listen '开始侦听 End Sub

利用Listener来侦听,代码如下:


@H_403_16@PrivateSubListener_ConnectionRequest(ByValrequestIDAsLong)

  1. @H_403_16@DimSockIndexAsInteger:SockIndex=8888

  2. @H_403_16@

  3. @H_403_16@DimiAsInteger

  4. @H_403_16@

  5. @H_403_16@'遍历控件

  6. @H_403_16@Fori=0ToSock.UBound

  7. @H_403_16@IfSock(i).State=0ThenSockIndex=i

  8. @H_403_16@Next

  9. @H_403_16@

  10. @H_403_16@IfSockIndex=8888Then

  11. @H_403_16@LoadSock(Sock.UBound+1)

  12. @H_403_16@SockIndex=Sock.UBound

  13. @H_403_16@EndIf

  14. @H_403_16@

  15. @H_403_16@'接受请求

  16. @H_403_16@Sock(SockIndex).Accept(requestID)

  17. @H_403_16@EndSub

Private Sub Listener_ConnectionRequest(ByVal requestID As Long) Dim SockIndex As Integer: SockIndex = 8888 Dim i As Integer '遍历控件 For i = 0 To Sock.UBound If Sock(i).State = 0 Then SockIndex = i Next If SockIndex = 8888 Then Load Sock(Sock.UBound + 1) SockIndex = Sock.UBound End If '接受请求 Sock(SockIndex).Accept (requestID) End Sub

当有客户端需要连接服务器时会触发Listener_ConnectionRequest事件,此时会遍历Sock控件数组,如果里面有空闲的Sock则用这个空闲的Sock和客户端进行连接,如果没有空闲的则重新Load一个进来。这里俺将SockIndex赋了个8888的值,这是因为用于和客户端连接的Sock控件数组的下标为0,为了省事所以赋了个8888,这个方法不***全的,所以大家别学我,呵呵

当客户端和服务器端成功连接后就可以利用Sock控件数组来和客户端相互传递数据了,当客户端将数据发送给服务器端时会触发Sock_DataArrival事件,代码如下:


@H_403_16@Private@H_403_16@Sub@H_403_16@Sock_DataArrival(IndexAs@H_403_16@Integer@H_403_16@,ByVal@H_403_16@bytesTotalAs@H_403_16@Long@H_403_16@)

  1. @H_403_16@Dim@H_403_16@strGetAs@H_403_16@String@H_403_16@

  2. @H_403_16@

  3. @H_403_16@'接收字符串并写入text中@H_403_16@

  4. @H_403_16@Sock(Index).GetDatastrGet

  5. @H_403_16@Text2.Text=strGet

  6. @H_403_16@End@H_403_16@Sub@H_403_16@

Private Sub Sock_DataArrival(Index As Integer,ByVal bytesTotal As Long) Dim strGet As String '接收字符串并写入text中 Sock(Index).GetData strGet Text2.Text = strGet End Sub

Index参数代表正在和客户端保持连接的Sock控件数组的序号,而bytesTotal代表数据的长度(汗,这样解释貌似不怎么对)

,利用GetData方法即可以将数据读取出来。

如果服务器想给客户端发送数据,则直接用SendData方法即可,如下所示:


@H_403_16@Dim@H_403_16@strSendasString@H_403_16@

  1. @H_403_16@Sock(Index).SendDatastrSend

Dim strSend as String Sock(Index).SendData strSend

Index代表的是Sock数组的序号,如果想给所有保持连接的客户端都发送相同的内容,则可以遍历一下Sock数组,然后挨个发送就是了,如下所示:


@H_403_16@For@H_403_16@i=0To@H_403_16@Sock.UBound

  1. @H_403_16@If@H_403_16@Sock(i).State=7Then@H_403_16@

  2. @H_403_16@Sock(i).SendData"范例"@H_403_16@

  3. @H_403_16@End@H_403_16@If@H_403_16@

  4. @H_403_16@Next@H_403_16@i

For i = 0 To Sock.UBound If Sock(i).State = 7 Then Sock(i).SendData "范例" End If Next i

如果服务器端想关闭某个连接,则需要关闭对应的Sock(),如下所示:


@H_403_16@Sock(Index).Close

Sock(Index).Close

上面的这些代码演示了如何实现一个简单的C/S结构服务器和客户端连接。俺只是个业余编程爱好者,虽然VB很简单但学习的时候也是着实费了不少力气,为了能给以后的初学者提供一点参考的范例所以俺写了这篇短文,并且尽量采用简单的语言来给大家演示,希望能对初学者有点帮助。

猜你在找的VB相关文章