电竞比分网-中国电竞赛事及体育赛事平台

分享

VB6 通過winsock控件數(shù)組實(shí)現(xiàn)客戶端和服務(wù)器多對(duì)一通信

 網(wǎng)絡(luò)摘記 2014-10-03

VB6 通過winsock控件數(shù)組實(shí)現(xiàn)客戶端和服務(wù)器多對(duì)一通信

注意:本文轉(zhuǎn)載自http://blog.csdn.net/geohuskyer/article/details/6261062

說(shuō)明:我是在最近開發(fā)一個(gè)考試系統(tǒng)過程中搜索到上面文章的,它提供的思想非常實(shí)用。當(dāng)然,這篇文章僅提供了一個(gè)基本思路,詳細(xì)的實(shí)現(xiàn)在人民郵電出版社出版的《Visual Basic網(wǎng)絡(luò)通信協(xié)議分析與應(yīng)用實(shí)現(xiàn)》(汪曉平 鐘軍等編著)有更精彩的,在4.3《Winsock控件實(shí)現(xiàn)TCP聊天》一章,供開發(fā)者參考。

上面引用文章的原文如下:

使用winsock控件可以實(shí)現(xiàn)客戶端和服務(wù)器間C/S結(jié)構(gòu)的通信,如果把客戶端和服務(wù)器放置于同一臺(tái)電腦中,并且將客戶端winsock的RemoteHost設(shè)置為本機(jī)IP,則可以實(shí)現(xiàn)客戶端程序和服務(wù)端程序間的自由通信。在應(yīng)用程序之間采用winsock通信比內(nèi)存共享等方法更簡(jiǎn)單快捷,同時(shí)也更安全。

 

在客戶端中添加一個(gè)窗體,拖拽一個(gè)winsock控件到該窗體上。

Private Sub Form_Load()  
  1. Me.Winsock1.RemoteHost = "192.168.1.5"  
  2. Me.Winsock1.RemotePort = 10002  
  3. Me.Winsock1.Connect  
  4. End Sub  
Private Sub Form_Load() Me.Winsock1.RemoteHost = "192.168.1.5" Me.Winsock1.RemotePort = 10002 Me.Winsock1.Connect End Sub

RemoteHost代表需要連接的遠(yuǎn)程服務(wù)器IP地址,局域網(wǎng)中的通信可以使用路由器分配的IP地址。

RemotePort代表端口號(hào),服務(wù)器和客戶端通過該端口進(jìn)行連接。

 

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)  
  1. Dim strGet As String  
  2.   
  3. '接收字符串并寫入Text1控件中   
  4. Winsock1.GetData strGet  
  5. Text1.Text = strGet  
  6. End Sub  
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim strGet As String '接收字符串并寫入Text1控件中 Winsock1.GetData strGet Text1.Text = strGet End Sub

當(dāng)客戶端的winsock接收到服務(wù)器發(fā)送來(lái)的數(shù)據(jù)后會(huì)觸發(fā)Winsock1_DataArrival事件,利用GetData方法可以將數(shù)據(jù)讀取出來(lái),一般來(lái)說(shuō)將數(shù)據(jù)讀取到byte()數(shù)組中是最好的,因?yàn)槔米止?jié)數(shù)組可以收發(fā)圖片、音頻等文件,本例中為了演示所以直接用一個(gè)字符串變量來(lái)讀取數(shù)據(jù)了。

 

Dim strSet As String  
  1. Winsock1.SendData strSet  
Dim strSet As String Winsock1.SendData strSet

客戶端向服務(wù)器發(fā)送數(shù)據(jù)可以用SendData方法,該方法同樣可以發(fā)送字節(jié)數(shù)組,這里為了演示所以發(fā)送了個(gè)字符串。

服務(wù)器端為了能同時(shí)和很多個(gè)不同的客戶端進(jìn)行通信,所以需要采用winsock控件數(shù)組,在服務(wù)器窗體中拖拽一個(gè)winsock控件,將其名稱更改為L(zhǎng)istener,該控件用于接收客戶端的連接請(qǐng)求。再拖拽一個(gè)winsock控件到窗體中,然后將其Index屬性更改為0,0即代表該控件是一個(gè)控件數(shù)組,為了使用方便所以把控件名稱更改為Sock,該控件數(shù)組用于動(dòng)態(tài)的和不同的客戶端通信。

在服務(wù)器端的窗口中寫入如下代碼:

Private Sub Form_Load()  
  1. Load Sock(0)  
  2. Listener.LocalPort = 10002   '端口號(hào)   
  3. Listener.Listen             '開始偵聽   
  4. End Sub  
Private Sub Form_Load() Load Sock(0) Listener.LocalPort = 10002 '端口號(hào) Listener.Listen '開始偵聽 End Sub

 

利用Listener來(lái)偵聽,代碼如下:

Private Sub Listener_ConnectionRequest(ByVal requestID As Long)  
  1. Dim SockIndex As Integer: SockIndex = 8888  
  2.   
  3. Dim i As Integer  
  4.   
  5. '遍歷控件  
  6. For i = 0 To Sock.UBound  
  7.     If Sock(i).State = 0 Then SockIndex = i  
  8. Next  
  9.   
  10. If SockIndex = 8888 Then  
  11.     Load Sock(Sock.UBound + 1)  
  12.     SockIndex = Sock.UBound  
  13. End If  
  14.   
  15. '接受請(qǐng)求  
  16. Sock(SockIndex).Accept (requestID)  
  17. End Sub  
Private Sub Listener_ConnectionRequest(ByVal requestID As Long) Dim SockIndex As Integer: SockIndex = 8888 Dim i As Integer '遍歷控件 For i = 0 To Sock.UBound If Sock(i).State = 0 Then SockIndex = i Next If SockIndex = 8888 Then Load Sock(Sock.UBound + 1) SockIndex = Sock.UBound End If '接受請(qǐng)求 Sock(SockIndex).Accept (requestID) End Sub

 

當(dāng)有客戶端需要連接服務(wù)器時(shí)會(huì)觸發(fā)Listener_ConnectionRequest事件,此時(shí)會(huì)遍歷Sock控件數(shù)組,如果里面有空閑的Sock則用這個(gè)空閑的Sock和客戶端進(jìn)行連接,如果沒有空閑的則重新Load一個(gè)進(jìn)來(lái)。這里俺將SockIndex賦了個(gè)8888的值,這是因?yàn)橛糜诤涂蛻舳诉B接的Sock控件數(shù)組的下標(biāo)為0,為了省事所以賦了個(gè)8888,這個(gè)方法不太安全的,所以大家別學(xué)我,呵呵

 

當(dāng)客戶端和服務(wù)器端成功連接后就可以利用Sock控件數(shù)組來(lái)和客戶端相互傳遞數(shù)據(jù)了,當(dāng)客戶端將數(shù)據(jù)發(fā)送給服務(wù)器端時(shí)會(huì)觸發(fā)Sock_DataArrival事件,代碼如下:

Private Sub Sock_DataArrival(Index As Integer, ByVal bytesTotal As Long)  
  1. Dim strGet As String  
  2.   
  3. '接收字符串并寫入text中   
  4. Sock(Index).GetData strGet  
  5. Text2.Text = strGet  
  6. End Sub  
Private Sub Sock_DataArrival(Index As Integer, ByVal bytesTotal As Long) Dim strGet As String '接收字符串并寫入text中 Sock(Index).GetData strGet Text2.Text = strGet End Sub

Index參數(shù)代表正在和客戶端保持連接的Sock控件數(shù)組的序號(hào),而bytesTotal代表數(shù)據(jù)的長(zhǎng)度(汗,這樣解釋貌似不怎么對(duì))

,利用GetData方法即可以將數(shù)據(jù)讀取出來(lái)。

 

如果服務(wù)器想給客戶端發(fā)送數(shù)據(jù),則直接用SendData方法即可,如下所示:

Dim strSend as String  
  1. Sock(Index).SendData strSend  
Dim strSend as String Sock(Index).SendData strSend

Index代表的是Sock數(shù)組的序號(hào),如果想給所有保持連接的客戶端都發(fā)送相同的內(nèi)容,則可以遍歷一下Sock數(shù)組,然后挨個(gè)發(fā)送就是了,如下所示:

For i = 0 To Sock.UBound  
  1.     If Sock(i).State = 7 Then  
  2.        Sock(i).SendData "范例"  
  3.     End If  
  4. Next i  
For i = 0 To Sock.UBound If Sock(i).State = 7 Then Sock(i).SendData "范例" End If Next i

 

如果服務(wù)器端想關(guān)閉某個(gè)連接,則需要關(guān)閉對(duì)應(yīng)的Sock(),如下所示:

Sock(Index).Close  
Sock(Index).Close

 

上面的這些代碼演示了如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的C/S結(jié)構(gòu)服務(wù)器和客戶端連接。俺只是個(gè)業(yè)余編程愛好者,雖然VB很簡(jiǎn)單但學(xué)習(xí)的時(shí)候也是著實(shí)費(fèi)了不少力氣,為了能給以后的初學(xué)者提供一點(diǎn)參考的范例所以俺寫了這篇短文,并且盡量采用簡(jiǎn)單的語(yǔ)言來(lái)給大家演示,希望能對(duì)初學(xué)者有點(diǎn)幫助。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多