4.3 服务器端的程序  1. 在服务器端创建一个新的工程将其命名为“ServerPrj”。  2. 将缺省窗体命名为“frmServer”。  3. 在窗体中添加一个ListBox控件,将其命名为“lstReceive”。  4. 在窗体中添加三个WinSock控件,将其分别命名为“sckListen”,sckBusy和“sckServer”并将“sckServer”的“Index”属性设置为0。  5. 在窗体中添加如下代码.。  '最大通道数  Private MaxChan As Integer  Private Sub Form_Load()  Dim i As Integer  MaxChan = 10   For i = 1 To MaxChan - 1   Load sckServer(i)  Next i  sckListen.LocalPort = 1000  sckListen.Listen  End Sub  Private Sub sckBusy_Close()  sckBusy.Close  End Sub  Private Sub sckBusy_DataArrival(ByVal bytesTotal As Long)  sckBusy.SendData "服务器忙,请稍后再连接!"  DoEvents  End Sub  Private Sub sckListen_ConnectionRequest(ByVal requestID As Long)  Dim i As Integer  '决定由哪一Winsock接受请求  For i = 0 To MaxChan - 1   If sckServer(i).State = 0 Then   Exit For   End If  Next i  If sckServer(i).State = 0 Then   sckServer(i).Accept requestID   Exit Sub  End If  '如果所有Winsock都用完则由专门的“忙”Winsock接受请求,以免用户要求得不到响应  sckBusy.Close  sckBusy.Accept requestID  End Sub  Private Sub sckListen_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, _ ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)  sckListen.Close  sckListen.LocalPort = 1000  sckListen.Listen  End Sub  Private Sub sckServer_Close(Index As Integer)  sckServer(Index).Close  End Sub  Private Sub sckServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)  Dim s As String  Dim i As Integer  sckServer(Index).GetData s  If UCase(Left(Trim(s), 2)) = "PT" Then '判断是否为悄悄话,点对点方式   If IsNumeric(Mid(Trim(s), 3, 1)) Then   i = Mid(Trim(s), 3, 1)   sckServer(i).SendData "Channel " & Index & " " & Right(Trim(s), Len(Trim(s)) - 3)   DoEvents   End If  Else '广播方式   For i = 0 To MaxChan - 1   '利用winsock的State属性给所有连接在服务器上的客户发消息   If sckServer(i).State = 7 Then   sckServer(i).SendData "Channel " & Index & " " & Trim(s)   DoEvents   End If   Next i  End If  lstReceive.AddItem "Channel " & Index & " " & Trim(s)  End Sub  Private Sub sckServer_Error(Index As Integer, ByVal Number As Integer, Description As String, _  ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As _  Long, CancelDisplay As Boolean)  sckServer(Index).Close  End Sub  从程序中可以看到:第一,程序中限制了通道数(10路)。第二,通过判断WinSock控件的State属性是否为0(关闭状态),来重新使用已关闭的WinSock控件。第三,通过给WinSock控件传递的信息加上包头,来对信息进行不同的处理(程序中若信息前加上了“PT"(Private Talk)+"通道数”的包头,由此就知道客户想要同拥有此“通道数”的另一客户进行“悄悄话”,否则就以广播方式将信息发给所有客户)。
  五) 结束语  WinSock控件不仅仅是用来编制网上聊天程序,而且可以用来编制各种网络游戏或网络通信程序。实际上WinSock控件是编制各种C/S程序的利器。在实际使用中通常是将WinSock控件封装在Activex DLL(进程内)、Activex EXE(进程外)部件的类中(类中引用)来使用的。通过区分所传信息前的不同的包头,用RaiseEvent命令引发不同 的事件,再对事件分别进行处理。这样不仅增加了程序的可调试性和安全性,而且更符合事件驱动编程方法的特点。