VB中WINSOCK下TCP连接的问题

2024年11月30日 15:35
有4个网友回答
网友(1):

我这儿有个例子,这是我做局域网聊天软件的服务器,用的就是动态控件数组实现的,现在限制最大连接数为15,当然可以更改。这只是服务器的代码,只有一个窗体,窗体代码如下:

Private intMax, XxintMax As Long '记录网络控件下标
Dim yhs As Integer '记录已连接人数

Private Sub Command2_Click()
sckServer(intMax).Close
End Sub

Private Sub Form_Load()
Connect
Label1.Caption = "当前连接用户数:0"
intMax = 0
XxintMax = 1
sckServer(0).LocalPort = "15000"
sckServer(0).Listen
XinXi(0).LocalPort = "20000"
XinXi(0).Listen
lianjieshu = 0
yhs = 0
End Sub

Private Sub Form_Unload(Cancel As Integer)
If sckServer(0).State Then sckServer(0).Close
End Sub
Private Sub xinxi_ConnectionRequest(Index As Integer, ByVal requestID As Long) '信息控件
Dim indexi, indexb As Integer '查找空闲控件
If Index = 0 Then
indexb = 1
For indexi = 1 To XxintMax
If Xxljzt(indexi, 1) = 0 Then
Xxljzt(indexi, 1) = 1
indexb = 0
Exit For
End If
Next indexi
If indexb = 1 Then
XxintMax = XxintMax + 1
indexi = XxintMax
Xxljzt(indexi, 1) = 1
'Else
'GoTo jz
End If
On Error Resume Next
Load XinXi(indexi)
jz: XinXi(indexi).LocalPort = "20000"
XinXi(indexi).Accept requestID
End If
'MsgBox "有用户连上了"
End Sub
Private Sub xinxi_DataArrival(Index As Integer, ByVal bytesTotal As Long) '信息控件有新信息
Dim strdata, id, neirong, IP As String
Dim i As Integer '转发信息ID
XinXi(Index).GetData strdata, vbString '当有数据到达时,调用GetData方法接收之
If Left(strdata, 1) = "T" Then
id = Trim(Mid(strdata, 4, Val(Mid(strdata, 3, 1))))
IP = Right(strdata, Len(strdata) - (Len(id) + 3))
i = xinxifs(Val(id))
XinXi(i).SendData ("T" & Len(Trim(Str(Xxljzt(Index, 2)))) & Trim(Str(Xxljzt(Index, 2))) & IP)
ElseIf Left(strdata, 1) = "F" Then
id = Trim(Mid(strdata, 4, Val(Mid(strdata, 3, 1))))
i = xinxifs(Val(id))
XinXi(i).SendData ("F")
ElseIf Left(strdata, 1) = "J" Then
id = Trim(Mid(strdata, 4, Val(Mid(strdata, 3, 1))))
i = xinxifs(Val(id))
XinXi(i).SendData (strdata)
Else
id = Trim(Mid(Trim(strdata), 2, Val(Left(Trim(strdata), 1))))
neirong = Right(Trim(strdata), Len(Trim(strdata)) - Len(id) - 1)
i = xinxifs(Val(id))
XinXi(i).SendData (Len(Str(Xxljzt(Index, 2))) & Str(Xxljzt(Index, 2)) & neirong)
End If
End Sub
Private Sub xinxi_Close(Index As Integer) '用户下线
If XinXi(Index).State <> sckClosed Then
XinXi(Index).Close
End If
Xxljzt(Index, 1) = 0
lianjieshu = lianjieshu - 1
Label1.Caption = "当前连接用户数 :" & Str(lianjieshu)

End Sub

Private Sub sckserver_ConnectionRequest(Index As Integer, ByVal requestID As Long) '登录控件
Dim indexi, indexb As Integer '查找空闲控件
If Index = 0 Then
indexb = 1
For indexi = 1 To intMax
If ljzt(indexi) = 0 Then
indexb = 0
Exit For
End If
Next indexi
If indexb = 1 Then
intMax = intMax + 1
indexi = intMax
Else
GoTo jz
End If
Load sckServer(indexi)
jz: sckServer(indexi).LocalPort = "15000"
sckServer(indexi).Accept requestID
'Load txtData(intMax)
End If
'MsgBox "有用户连上了"
End Sub
Private Sub sckserver_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim strdata, sql, id, password As String
sckServer(Index).GetData strdata, vbString '当有数据到达时,调用GetData方法接收之
id = Mid(strdata, 1, InStr(strdata, "\") - 1)
password = Right(strdata, Len(strdata) - InStr(strdata, "\"))
sql = "select * from mima where ID=" & Val(Trim(id)) & " and password='" & password & "'"
Set cx = New ADODB.Recordset
cx.CursorLocation = adUseClient
cx.Open sql, conn, 2, 2
If Not cx.EOF Then
sckServer(Index).SendData ("1")
ljzt(Index) = 1
lianjieshu = lianjieshu + 1
Label1.Caption = "当前连接用户数 :" & Str(lianjieshu)
Xxljzt(xinxifree, 2) = Val(Trim(id))
Else
sckServer(Index).SendData ("0")
End If
Set cx = Nothing
Me.Cls
Print Index
End Sub
Private Sub sckserver_Close(Index As Integer) '断开登录
If sckServer(Index).State <> sckClosed Then
sckServer(Index).Close
End If
ljzt(Index) = 0
Form1.Print Index & "close"
End Sub

Private Function xinxifree() As Integer '信息控件查找空闲连接
Dim i As Integer
For i = 1 To 15
If Xxljzt(i, 1) = 0 Then
xinxifree = i
Exit Function
End If
Next i
End Function
Private Function xinxifs(id As Integer) As Integer '查找信息是给谁发的
Dim i As Integer
For i = 1 To 15
If Xxljzt(i, 2) = id Then
xinxifs = i
Exit Function
End If
Next i
End Function

这是模块中的代码:

Public conn As ADODB.Connection '用户基本信息表
Public cx As ADODB.Recordset
Public lianjieyh() As Integer '记录已连接用户的ID
Public lianjieshu As Integer '记录有多少用户登录
Public ljzt(1 To 15) '记录网络控件空闲状态及该控件对应有用户
Public Xxljzt(1 To 15, 1 To 2) As Integer '记录聊天状态

Sub Connect()
Set conn = New ADODB.Connection
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\yh.mdb"
conn.Open
End Sub

希望对你有所帮助

网友(2):

同一时间只有一个在侦听,当有人连接时,在侦听的控件转为接受连接。然后就可以马上读入另一个控件,继续侦听。

其实就是用控件数组了。采用动态读入,有多少用户同时连接就有多少个控件在工作。

还有一点,在用户关闭连接后,那个控件元素到底是卸载还是等又有新用户来时重用,代码上要写清楚,这样可以提高效率和降底资源占用。

网友(3):

你只需要用一个SOCK控件就可以侦听所有客户端,当有客户申请连接,它就接受连接,并继续侦听其他客户端的请求。

网友(4):

可以。你只要动态加载出你想并发连接数量的winsock就可以了