用winsock数组实现,我自己写了个工时统计小软件就是实现多客户端连接服务器。。tcp vb三层结构实现的。关键代码: Private Sub sckListen_ConnectionRequest(ByVal requestID As Long) Dim i As Long
'遍历数组查找空闲的套接字 For i = 0 To tcpServer.UBound If tcpServer(i).State = sckClosed Then '找到空闲的套接字 tcpServer(i).accept requestID '接受连接 Exit Sub End If Next '如果上面未找到,则增加一个新的套接字 Load tcpServer(i) tcpServer(i).LocalPort = 0 tcpServer(i).accept requestID '接受连接
建立一个侦听 Sock 和 连接用的 Sock数组,由侦听那个 Listener.Listen 后, Listener_ConnectionRequest(ByVal requestID As Long) 取得 requestID 交给负责建立连接的数组 Sock(SockIndex).Accept (requestID) 响应连接。 中间你需要建立与 SockIndex 对应的状态存储数组,存储每个用于建立连接的sock数组元素的连接状态,接收到 ConnectionRequest 事件后,从sock数组中取得空闲sock号SockIndex ,用空闲的这些来接受客户端连接。大致代码如下: '远程计算机请求连接 Private Sub Listener_ConnectionRequest(ByVal requestID As Long) Dim SockIndex As Integer Dim tt As SingleOn Error GoTo errChk '查找空闲的sock SockIndex = FindFreeSocket() If SockIndex = 0 Then Exit Sub'连接数超载 Sock(SockIndex).Accept (requestID) '无法判断是否与客户端建立连接成功,改为在接收数据时确认连接成功。 CantConn: Exit Sub errChk: Sock_Close (SockIndex) '先关闭连接Sock(SockIndex).Close '先关闭连接 If Sock(SockIndex).State <> sckClosed Then Resume CantConn End Sub'寻找空闲的sock Private Function FindFreeSocket() As Integer Dim SockCount As Integer, i As Integer SockCount = Connlimte For i = 1 To SockCount If Sock(i).State = 0 Then 'ConnSt(i).State = FREE,直接检查Sock的状态,省得有延迟 FindFreeSocket = i Exit Function End If Next i '超载 If (SockCount + 1) < ConnaboveLimit Then'小于设定的连接数上限。 'ReDim Preserve ConnSt(SockCount + 1) Connlimte = SockCount + 1 FindFreeSocket = Connlimte '动态增加连接限制上限 Load Sock(Connlimte) Else
FindFreeSocket = 0 Connlimte = aboveConn '非正常超载,还原原先设置的连接上限. '连接数非正常超载:请求连接数已达到上限' End If End Function 中间需要考虑连接数超出预定数量时的处理方法,另外建议开始侦听前,先 Load 足够数量的 Sock元素,若都在ConnectionRequest中Load Sock的话达到一定数量连接后,响应之后多余的连接请求就会因为 Load sock的资源消耗而变得异常缓慢,关于这点楼主可以模拟1000个客户端连接试试就知道了。
即可监听到连接本机的 6000 端口的数据
Private Sub sckListen_ConnectionRequest(ByVal requestID As Long)
Dim i As Long
'遍历数组查找空闲的套接字
For i = 0 To tcpServer.UBound
If tcpServer(i).State = sckClosed Then '找到空闲的套接字
tcpServer(i).accept requestID '接受连接
Exit Sub
End If
Next
'如果上面未找到,则增加一个新的套接字
Load tcpServer(i)
tcpServer(i).LocalPort = 0
tcpServer(i).accept requestID '接受连接
'为此套接字增加一个超时检测定时器
Load sckTimer(i)
sckTimer(i).Enabled = False
sckTimer(i).Interval = 60000 '设置超时检测为1秒
End Sub
不難解決
Listener_ConnectionRequest(ByVal requestID As Long)
取得 requestID 交给负责建立连接的数组 Sock(SockIndex).Accept (requestID) 响应连接。
中间你需要建立与 SockIndex 对应的状态存储数组,存储每个用于建立连接的sock数组元素的连接状态,接收到 ConnectionRequest 事件后,从sock数组中取得空闲sock号SockIndex ,用空闲的这些来接受客户端连接。大致代码如下:
'远程计算机请求连接
Private Sub Listener_ConnectionRequest(ByVal requestID As Long)
Dim SockIndex As Integer
Dim tt As SingleOn Error GoTo errChk
'查找空闲的sock
SockIndex = FindFreeSocket()
If SockIndex = 0 Then Exit Sub'连接数超载
Sock(SockIndex).Accept (requestID) '无法判断是否与客户端建立连接成功,改为在接收数据时确认连接成功。
CantConn:
Exit Sub
errChk: Sock_Close (SockIndex) '先关闭连接Sock(SockIndex).Close '先关闭连接 If Sock(SockIndex).State <> sckClosed Then
Resume CantConn
End Sub'寻找空闲的sock
Private Function FindFreeSocket() As Integer
Dim SockCount As Integer, i As Integer
SockCount = Connlimte
For i = 1 To SockCount
If Sock(i).State = 0 Then 'ConnSt(i).State = FREE,直接检查Sock的状态,省得有延迟
FindFreeSocket = i
Exit Function
End If
Next i
'超载
If (SockCount + 1) < ConnaboveLimit Then'小于设定的连接数上限。
'ReDim Preserve ConnSt(SockCount + 1)
Connlimte = SockCount + 1
FindFreeSocket = Connlimte
'动态增加连接限制上限
Load Sock(Connlimte)
Else
FindFreeSocket = 0
Connlimte = aboveConn '非正常超载,还原原先设置的连接上限.
'连接数非正常超载:请求连接数已达到上限'
End If
End Function
中间需要考虑连接数超出预定数量时的处理方法,另外建议开始侦听前,先 Load 足够数量的 Sock元素,若都在ConnectionRequest中Load Sock的话达到一定数量连接后,响应之后多余的连接请求就会因为 Load sock的资源消耗而变得异常缓慢,关于这点楼主可以模拟1000个客户端连接试试就知道了。
比如发送abcd
发消息的关键代码如下:Private Sub Timer1_Timer()
'=====================================================
'遍历套接字数组,对处于连接状态的发送检测请求
For j = 0 To tcpServer.UBound
If tcpServer(j).State <> sckClosed Then
tcpServer(j).SendData strRetrun '发送检测数据
sckTimer(j).Tag = 1
sckTimer(j).Enabled = True '启动超时检测
End If
strRetrun 就是你要发的"abcd",我自己写的还不是太完善;只是给自己的部门用。
这个在于客户端的设计,你的每个客户端需要给自己编一个能唯一识别的标识ID,就像两个双胞胎在一起时,你不给他们加以区别你是分不清谁是谁的,然后连接时将ID发送到服务端,而服务端要做的事情就是将客户端的连接线程号(Sock(SockIndex)中的SockIndex)与客户端发送来的ID进行对应管理,这样你就可以通过客户端ID来区分每个客户端来进行消息发送了。我上面的代码就是做一个这种项目时找来的参考代码,我的客户端是一堆使用手机卡通过GPRS与服务器进行通讯的电子显示屏,每个客户端有一个自己的ID号,我做的是服务端,服务端需要将数据库中各客户端ID对应的消息发送给正确的客户端以显示,而客户端登录服务器的时候会向服务端提交它自身的ID号,这样我就能准确区分客户端是谁了。剩下的就是你的客户端进行唯一ID标识的问题了,这个属于管理范畴,不在这里多说了。