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

在VB6中使用winsock控件需要引用Microsoft Winsock Control 6.0部件

 

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

 

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

[vb]  view plain copy
  1. Private Sub Form_Load()  
  2. Me.Winsock1.RemoteHost = "192.168.1.5"  
  3. Me.Winsock1.RemotePort = 10002  
  4. Me.Winsock1.Connect  
  5. End Sub  

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

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

 

[vb]  view plain copy
  1. Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)  
  2. Dim strGet As String  
  3.   
  4. '接收字符串并写入Text1控件中  
  5. Winsock1.GetData strGet  
  6. Text1.Text = strGet  
  7. End Sub  

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

 

[vb]  view plain copy
  1. Dim strSet As String  
  2. Winsock1.SendData strSet  

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

 

 

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

 

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

[vb]  view plain copy
  1. Private Sub Form_Load()  
  2. Load Sock(0)  
  3. Listener.LocalPort = 10002   '端口号  
  4. Listener.Listen             '开始侦听  
  5. End Sub  

 

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

[c-sharp]  view plain copy
  1. Private Sub Listener_ConnectionRequest(ByVal requestID As Long)  
  2. Dim SockIndex As Integer: SockIndex = 8888  
  3.   
  4. Dim i As Integer  
  5.   
  6. '遍历控件  
  7. For i = 0 To Sock.UBound  
  8.     If Sock(i).State = 0 Then SockIndex = i  
  9. Next  
  10.   
  11. If SockIndex = 8888 Then  
  12.     Load Sock(Sock.UBound + 1)  
  13.     SockIndex = Sock.UBound  
  14. End If  
  15.   
  16. '接受请求  
  17. Sock(SockIndex).Accept (requestID)  
  18. End Sub  

 

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

 

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

[vb]  view plain copy
  1. Private Sub Sock_DataArrival(Index As IntegerByVal bytesTotal As Long)  
  2. Dim strGet As String  
  3.   
  4. '接收字符串并写入text中  
  5. Sock(Index).GetData strGet  
  6. Text2.Text = strGet  
  7. End Sub  

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

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

 

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

[vb]  view plain copy
  1. Dim strSend as String  
  2. Sock(Index).SendData strSend  

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

[vb]  view plain copy
  1. For i = 0 To Sock.UBound  
  2.     If Sock(i).State = 7 Then  
  3.        Sock(i).SendData "范例"  
  4.     End If  
  5. Next i  

 

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

[vb]  view plain copy
  1. Sock(Index).Close  

 

上面的这些代码演示了如何实现一个简单的C/S结构服务器和客户端连接。 经验证是正确的









1 通信程序通常都是采用Client/Server形式。这就要求作为服务器的主机可以同时处理多个客户的请求。因此在编写服务器程序时要添加多个Winsock控件。在开始我们先加入两个Winsock控件。其中一个用来侦听网上请求信号,取名为Listener;另外一个为初始的连接口,取名叫Sock( 0)。注意,后一个控件要设为动态数组的形式,以后当客户增多时,可在这个控件基础上动态增加。由于受资源限制,我们在本例中设定最多可以同时接纳15个客户。客户机一般只与一个主机相连,因此程序只须一个Winsock进行连接就足够了。这个程序要用到的控件较少,除了Winsock和Form控件外,只须再添加Commmand控件即可。下面是具体程序和详细注释。 
  2 ****************************** 
  3  ' 服务器程序 
  4 ****************************** 
  5  Option  Explicit 
  6 定义常量 
  7  Const BUSY  As  Boolean =  False 
  8  Const FREE  As  Boolean =  True 
  9 定义连接状态 
 10  Dim ConnectState()  As  Boolean 
 11  Private  Sub Form_Load() 
 12  ReDim Preserve ConnectState( 0  To  1
 13  On  Error  Resume  Next 
 14 ConnectState( 0) = FREE 
 15 ConnectState( 1) = FREE 
 16  ' 指定网络端口号 
 17  Listener.LocalPort =  1011 
 18  ' 开始侦听 
 19  Listener.Listen 
 20  End Sub 
 21  Private  Sub Listener_ConnectionRequest(ByVal requestID  As  Long
 22  Dim SockIndex  As  Integer 
 23  Dim SockNum  As  Integer 
 24  On  Error  Resume  Next 
 25 Form1.Print requestID &  " 连接请求 " 
 26  ' 查找连接的用户数 
 27  SockNum =  UBound(ConnectState) 
 28  If SockNum >  14  Then 
 29 Form1.Print SockIndex &  "" 
 30  Exit  Sub 
 31  End  If 
 32  ' 查找空闲的sock 
 33  SockIndex = FindFreeSocket() 
 34  ' 如果已有的sock都忙,而且sock数不超过15个,动态添加sock 
 35  If SockIndex > SockNum  Then 
 36 Load Sock(SockIndex) 
 37  End  If 
 38 ConnectState(SockIndex) = BUSY 
 39 Sock(SockIndex).Tag = SockIndex 
 40  ' 接受请求 
 41  Sock(SockIndex).Accept (requestID) 
 42 Form1.Print SockIndex &  " 接受请求 " 
 43  End Sub 
 44 
 45  ' 客户断开,关闭相应的sock 
 46  Private  Sub Sock_Close(Index  As  Integer
 47  If Sock(Index).State <> sckClosed  Then 
 48 Sock(Index).Close 
 49  End  If 
 50 ConnectState(Index) = FREE 
 51 Form1.Print Index &  " close " 
 52  End Sub 
 53 
 54  ' 接收数据 
 55  Private  Sub Sock_DataArrival(Index  As  Integer, ByVal bytesTotal  As  Long
 56  Dim dx  As  Double 
 57 Form1.Print  " 数据来自 " & Index 
 58 Sock(Index).GetData dx, vbDouble 
 59 Form1.Print  " dx= " & dx 
 60  End Sub 
 61 
 62  ' 寻找空闲的sock 
 63  Public  Function FindFreeSocket() 
 64  Dim SockCount, i  As  Integer 
 65 SockCount =  UBound(ConnectState) 
 66  For i =  0  To SockCount 
 67  If ConnectState(i) = FREE  Then 
 68 FindFreeSocket = i 
 69  Exit  Function 
 70  End Ifs 
 71  Next i 
 72  ReDim Preserve ConnectState( 0  To SockCount +  1
 73 FindFreeSocket =  UBound(ConnectState) 
 74  End Function 
 75 
 76 *************************** 
 77  ' 客户程序 
 78  ’*************************** 
 79  Option  Explicit 
 80  ' 发送数据 
 81  Private  Sub command1_Click() 
 82  Dim dx  As  Double 
 83 dx =  23.9 
 84 sock.SendData dx 
 85  MsgBox ( " data sended "
 86  End Sub 
 87 
 88  Private  Sub Form_Load() 
 89  ' 远程主机名 
 90  sock.RemoteHost =  " media2 " 
 91  ' 网络端口 
 92  sock.RemotePort =  1011 
 93  ' 发出连接命令 
 94  sock.Connect 
 95 Command1.Enabled =  False 
 96  End Sub 
 97 
 98  ' 服务器关闭 
 99  Private  Sub sock_Close() 
100  MsgBox ( " socket closed "
101  End Sub 
102 
103  ' 连接成功 
104  Private  Sub sock_Connect() 
105  MsgBox ( " socket connected "
106 Command1.Enabled =  True 
107  End Sub
复制代码

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值