MultiLink的WinSock Server程式

來源:cww

我們要先有一個觀念,在VB中,

1.一個WinSock 控制項(當Server)只能連結一個Client端的需求,所以Server要變成可多重
    連結,要有多個WinSock控制項,我們也可以使用Load 指令來動態產生
2.Server端必須設定好一個Local Port 當作其Listen的Port,所有Client端的RemotePort要
   指定Server 當Listen的Port Number,以本例來說,我設定3128當作Server Listen的
   Port,而我的程式中有一個WinSock Control (Winsock1(0))專門做Listen的動作。在本
   例中,我只允許有4個Cllient同時連上來,所以我在Form Load時,便動態產生4個
   WinSock ,含Listen  的那一個一共5個WinSock Control。
3.在Server端,如果ConnectionRequest Event產生了,代表有Client端提出需求,這時
   候,我們要選取一個沒有使用的WinSock Control來和Client連。
4.我們在Client中,設定LocalPort = 0 代表會選取一個空著的Port來和Server的Port來連
  在Server中   Winsock1(i).Accept requestID 便會自動為我們做這件事;這時,我們會看
  到Server端的會Assign一個RemotePort,而Client也會Assign一個LocalPort,這次的連
  線便是透過這組連線管道來做

該程式請將Client的程式做成.Exe再來重覆行,且Server的程式同時也要執行,當Client
端的Text1.Text = "Close" 來送給Server時,告知Server該Connection 可結束
其他相關的知識請查Help或其他書

註: GetData方法 的第一個參數 :如果傳回的資料是String則宣告成String,若告成Variant
   在VB環境下沒問題,但變成.exe後會有錯(Automation Error);當然,若傳的是Binary
   的資料,那就使用ByteArray來做
'以下是Server端程式,需一個ListBox,一個WinSock控制項
Option Explicit

Private Sub Form_Load()
Load Winsock1(1)
Load Winsock1(2)
Load Winsock1(3)
Load Winsock1(4)

Winsock1(0).LocalPort = 3128  '設定Listen的Port是3128,請自行改成您的電腦沒衝突的號碼
Winsock1(0).Listen
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim i As Long
For i = 0 To 4
   Winsock1(i).Close
Next
Unload Winsock1(1)
Unload Winsock1(2)
Unload Winsock1(3)
Unload Winsock1(4)
End Sub

Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
Dim i As Long
For i = 1 To 4
   If Winsock1(i).State = sckClosed Then
      Winsock1(i).Accept requestID
      List1.AddItem "Local Port=" + Str(Winsock1(i).LocalPort) + " RemotePort = " + Str(Winsock1(i).RemotePort)
      Exit For
   End If
Next
End Sub

Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
'Dim mydata As Variant
Dim mydata As String '註:如果傳回的資料是String則宣告成String,若告成Variant
                                      '在VB環境下沒問題,但變成.exe後會有錯(Automation Error)
Winsock1(Index).GetData mydata, vbString
List1.AddItem "From Socket" + Str(Index) + "  " + mydata
Winsock1(Index).SendData "WinSock" + Str(Index) + "Reply"
If mydata = "Close" Then
   Winsock1(Index).Close
End If
End Sub

'以下是Client端程式,需一個ListBox,一個WinSock控制項,三個Command Button
'與一個TextBox用來傳資料,
Option Explicit

Private Sub Command1_Click()
Winsock1.LocalPort = 0	'以便自動產生Local Port
Winsock1.Connect  "140.116.253.247" '設定改成您 Server 電腦的IP 號碼
End Sub

Private Sub Command2_Click()
Winsock1.SendData  "Close"  '通知Server端Close
DoEvents
Winsock1.Close
End Sub

Private Sub Command3_Click()
Winsock1.SendData Text1.Text
End Sub

Private Sub Form_Load()
Winsock1.RemotePort = 3128  '設定與Server端做Listen的Port相同
Command1.Caption = "Connect"
Command2.Caption = "Close"
Command3.Caption = "Send"
List1.Clear
End Sub

Private Sub Form_Unload(Cancel As Integer)
If Winsock1.State <> sckClosed Then
   Winsock1.SendData  "Close"
   DoEvents
   Winsock1.Close
   Winsock1.LocalPort = 0
End Sub

Private Sub Winsock1_Connect()
If Winsock1.State = sckConnected Then
   List1.AddItem "Connected! LocalPort =" + Str(Winsock1.LocalPort) + " RemptePort = " + Str(Winsock1.RemotePort)
End If

End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim mydata As String
Winsock1.GetData mydata, vbString
List1.AddItem mydata
End Sub

Private Sub Winsock1_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)
List1.AddItem Description
End Sub