(7)客户端接受在线好友的连接请求
在以服务端方式接受连接请求时,根据bUsedServer(i)判断与之对应的WinsockClientServer(i)是否被使用,如未使用,则通过Load方法将WinsockClientServer(i)控件动态载入,随后调用Accept方法接受客户端程序连接请求。
Public bUsedServer(1 To MaxOnlineFriend) As Boolean
Private Sub WinsockClientServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
If Index <> 0 Then Exit Sub
For i = 1 To MaxOnlineFriend
If Not bUsedServer(i) Then
Load WinsockClientServer(i)
WinsockClientServer(i).Accept requestID
bUsedServer(i) = True
Exit For
End If
Next i
End Sub
(8)客户端显示在线好友
当在线好友接受连接后,则将该在线好友的ID显示在列表框ListFriendID中,并将与该在线好友连接的Winsock的下标值加入另一个隐藏的列表框ListSockIndex中,两个列表框对应,以便后面从ID列表框中选择好友发送聊天消息时,能马上知道与该好友连接的Winsock下标值。
Private Sub WinsockClientClient_Connect(Index As Integer)
If Index = 0 Then Exit Sub
ListFriendID.AddItem OnlineFriendInfo(Index).UserID
ListSockIndex.AddItem Index
End Sub
2.聊天
完全在客户端程序之间进行。
(1)发送
注意聊天者发送聊天数据前先要在列表框ListFriendID中选择欲与之通话的好友ID。程序根据所选好友在ListFriendID列表框中的位置从与之对应的ListSockIndex列表框中找到WinsockClientClient控件的下标值,然后用该Winsock发送聊天内容,同时通过自定义过程SetRichColorText将聊天内容、聊天双方ID及时间以不同颜色显示在发送端聊天窗体的RichTextBox中,SetRichColorText过程的具体实现见源程序。
Private Sub CommandTcpSend_Click()
If ListFriendID.ListIndex < 0 Then Exit Sub
SockIndex = ListSockIndex.List(ListFriendID.ListIndex)
If WinsockClientClient(SockIndex).State = sckConnected Then
SetRichColorText CStr(Now), MyID, ListFriendID.Text, Text1.Text, False
WinsockClientClient(SockIndex).SendData Text1.Text & Chr(2)
DoEvents
End If
End Sub
(2)接收
接收时读取每条聊天内容,并根据发送方的IP地址WinsockClientServer(Index).RemoteHostIP从OnlineFriendInfo数组中找到发送方的ID,通过自定义过程SetRichColorText将聊天内容、聊天双方ID及时间以不同颜色显示在接收端聊天窗体的RichTextBox中。
Private Sub WinsockClientServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)
If Index = 0 Then Exit Sub
Dim tmpstr As String
Dim EndFlagLoc As Integer
WinsockClientServer(Index).GetData tmpstr, , bytesTotal
BufferMsg(Index) = BufferMsg(Index) & tmpstr
EndFlagLoc = InStr(BufferMsg(Index), Chr(2))
While EndFlagLoc > 0
strMsg = Left$(BufferMsg(Index), EndFlagLoc - 1)
For i = 1 To MaxOnlineFriend
If OnlineFriendInfo(i).IPAddr = WinsockClientServer(Index).RemoteHostIP Then Exit For
Next i
SetRichColorText CStr(Now), OnlineFriendInfo(i).UserID, MyID, strMsg, True
BufferMsg(Index) = Mid(BufferMsg(Index), EndFlagLoc + 1)
EndFlagLoc = InStr(BufferMsg(Index), Chr(2))
Wend
End Sub
3.离线
当一个用户离线时,作为聊天程序的服务器程序以及其他在线好友的聊天程序上与之通信的Winsock都会收到Close消息,此时要做一些处理工作。
(1)服务器程序
清除该在线用户的信息,卸载与之通信的WinsockServer控件。
Private Sub WinsockServer_Close(Index As Integer)
OnlineUserInfo(Index).bUsed = False
OnlineUserInfo(Index).bLogined = False
OnlineUserInfo(Index).IPAddr = ""
OnlineUserInfo(Index).UserID = ""
BufferRecv(Index) = ""
WinsockServer(Index).Close
Unload WinsockServer(Index)
End Sub
(2)客户端程序
卸载与之通信的WinsockClientClient控件,从ListFriendID列表框中清除该在线好友的 ID,从ListSockIndex列表框中清除该在线好友所对应WinsockClientClient控件的下标值,从OnlineFriendInfo数组中清除该在线好友的信息。
Private Sub WinsockClientClient_Close(Index As Integer)
WinsockClientClient(Index).Close
Unload WinsockClientClient(Index)
For i = 0 To ListFriendID.ListCount - 1
If ListFriendID.List(i) = OnlineFriendInfo(Index).UserID Then
ListFriendID.RemoveItem i
ListSockIndex.RemoveItem i
Exit For
End If
Next i
OnlineFriendInfo(Index).bUsed = False
OnlineFriendInfo(Index).IPAddr = ""
OnlineFriendInfo(Index).UserID = ""
BufferMsg(Index) = ""
End Sub
卸载与之通信的WinsockClientServer控件。
Private Sub WinsockClientServer_Close(Index As Integer)
If Index = 0 Then Exit Sub
bUsedServer(i) = False
WinsockClientServer(Index).Close
Unload WinsockClientServer(Index)
End Sub
本程序在VB6.0中已通过调试。
参考文献
[1]Anthony Jones著.WINDOWS网络编程技术.机械工业出版社,2000年3月.
|