|
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()
RemoteHost代表需要連接的遠(yuǎn)程服務(wù)器IP地址,局域網(wǎng)中的通信可以使用路由器分配的IP地址。 RemotePort代表端口號(hào),服務(wù)器和客戶端通過該端口進(jìn)行連接。
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
當(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
客戶端向服務(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()
利用Listener來(lái)偵聽,代碼如下:
Private Sub Listener_ConnectionRequest(ByVal requestID As Long)
當(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)
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
Index代表的是Sock數(shù)組的序號(hào),如果想給所有保持連接的客戶端都發(fā)送相同的內(nèi)容,則可以遍歷一下Sock數(shù)組,然后挨個(gè)發(fā)送就是了,如下所示:
For i = 0 To Sock.UBound
如果服務(wù)器端想關(guān)閉某個(gè)連接,則需要關(guān)閉對(duì)應(yīng)的Sock(),如下所示:
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)幫助。 |
|
|
來(lái)自: 網(wǎng)絡(luò)摘記 > 《VB知識(shí)》