郭 毅 涂婧璐
摘要:簡要介紹了VB網(wǎng)絡(luò)通信中收發(fā)數(shù)據(jù)的原理及方式,給出了UDP協(xié)議下通信的源代碼,通過在校園一卡通系統(tǒng)中的應(yīng)用實例,著重講述了一種利用計時器控件進行接收并處理多幀數(shù)據(jù)的簡易控制方法,并提供了實現(xiàn)方法的主要源代碼。文章的最后指出了這種方法的不足之處。
關(guān)鍵詞:網(wǎng)絡(luò)通信;多幀數(shù)據(jù);計時器控件
中圖分類號:TP311文獻標(biāo)識碼:A 文章編號:1009-3044(2008)18-20000-00
The Simple Method of The Multi-frame Data Receiving In VB Network Communication
GUO Yi,TU Jing-lu
(Department of Information Technology,Hainan Vocational College of Political Science and Law,Haikou 571100,China)
Abstract: The principles and methods of receieing data are introduced briefly in VB network communication, has given the source code which under the UDP protocol.Adopted in the campus card system of examples, focusing on the use of the timer controls to receive and process Multi-frame data simple control method. Finally,the article has pointed out the lack of this methods.
Key words:Network Communication; Multi-frame Data; Timer Control
1 引言
隨著網(wǎng)絡(luò)技術(shù)的發(fā)展,網(wǎng)絡(luò)應(yīng)用越來越深入人們的生活,由此引發(fā)的網(wǎng)絡(luò)設(shè)備及相應(yīng)軟件的開發(fā)工作也日益增
加。我們學(xué)院的校園一卡通系統(tǒng)就是在這個時期應(yīng)運而生的,并且隨著時代的發(fā)展、學(xué)院日益擴大的應(yīng)用需求而不斷更新升級。在最新增加的學(xué)生宿舍網(wǎng)絡(luò)收費功能的設(shè)計中,遇到了一個接收多幀數(shù)據(jù)的問題,現(xiàn)應(yīng)用一種簡易的方法解決,特與應(yīng)用VB6.0進行網(wǎng)絡(luò)通信設(shè)計的同仁們共享。
2 VB網(wǎng)絡(luò)通信
在一卡通的脫網(wǎng)消費系統(tǒng)中,由于消費記錄是暫時存在消費機中的,需要定時下載數(shù)據(jù)并清空,才不會導(dǎo)致因存儲器沒有空間而不允許刷卡的事情產(chǎn)生,但如果每天下載數(shù)據(jù)又會增加工作人員的工作量。由于我們所使用的消費機存儲容量可達(dá)32KB,而我們一條記錄只占用16B,這樣我們的一臺消費機中可存儲2048條記錄。以我院校園網(wǎng)規(guī)模來看,現(xiàn)通過校園網(wǎng)上網(wǎng)的學(xué)生在400人左右,即使只有一臺消費機每人每天消費扣款,也可存儲5天的數(shù)據(jù),但這樣一次傳輸?shù)缴衔粰C的數(shù)據(jù)量就比較大,因此我們的消費機把數(shù)據(jù)分成多幀來上傳(每一幀傳輸40條記錄,加上幀頭和幀尾共649個字節(jié)),這樣便產(chǎn)生了本文所提出的問題——如何利用Winsock控件的DataArrival事件來接收多幀數(shù)據(jù)?
VB5.0以上的版本都提供了Winsock控件,Winsock使用的TCP協(xié)議和UDP協(xié)議允許建立并保持一個到遠(yuǎn)程計算機上的連接,且可以在連接結(jié)束之前實時地進行數(shù)據(jù)交換。用戶僅通過設(shè)置屬性并借助事件處理就能夠輕而易舉地連接到一個遠(yuǎn)程的計算機上。
我們的消費系統(tǒng)采用的是UDP協(xié)議,它是無連接的,并不保證數(shù)據(jù)傳輸?shù)目煽啃浴⒂行蛐院蜔o重復(fù)性,因此需要程序員負(fù)責(zé)管理數(shù)據(jù)報文的排序和可靠性,這對程序的嚴(yán)謹(jǐn)性也有了更高的要求。下面我們把在VB6.0中使用Winsock控件實現(xiàn)UDP協(xié)議的方法簡單地描述一下,在這里上位機為本地機器,下位機(消費機)視為遠(yuǎn)程計算機。
在程序中用到的Winsock控件的主要屬性如下表所示:
表1Winsock控件的屬性
由于UDP協(xié)議是無連接的,不保證接收端是否在偵聽,所以使用的方法也比較少,本系統(tǒng)中用到的主要方法有:Bind、SendData和GetData等方法,其中Bind方法用于綁定本地端口;SendData方法用于發(fā)送數(shù)據(jù);GetData方法一般用于DataArrival事件中,獲取當(dāng)前數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)并將其存儲在變體類型的變量中。在程序中所用到的屬性一般在窗體加載時便設(shè)置好,并使用Bind方法來綁定本地端口,代碼如下:
Dim a as Integer ‘?dāng)?shù)組下標(biāo)計數(shù)器
Dim b as Integer ‘幀計數(shù)器
Dim revHead() as Byte ‘存放收到的所有數(shù)據(jù)的數(shù)組
Dim intfrmcount as integer ‘總幀數(shù)
Private Sub Form_Load()
sckMultFrm.RemoteHost = IPadd ‘設(shè)置遠(yuǎn)程IP
sckMultFrm.RemotePort = 5010 ‘設(shè)置遠(yuǎn)程端口
sckMultFrm.LocalPort = 5009 ‘設(shè)置本地端口
sckMultFrm.Bind 5009 ‘綁定本地端口
End Sub
通過單擊命令按鈕事件來發(fā)送命令,代碼如下:
Private Sub Send_Click()
Dim bytreadRecord() As Byte
sckMultFrm.SendData bytreadRecord ‘發(fā)送命令,其中bytreadRecord為字節(jié)型數(shù)組
a = 0:b = 0 ‘計數(shù)器清零
Timer1.Interval = 2000 ‘預(yù)計第一幀數(shù)據(jù)接收并處理完的時間為2S
End Sub
當(dāng)消費機有數(shù)據(jù)上傳時,將觸發(fā)Winsock控件的DataArrival事件,該事件當(dāng)新數(shù)據(jù)到達(dá)時發(fā)生。這里將每次收到的幀數(shù)據(jù)都保存到一個一維數(shù)組中,具體代碼如下:
Private Sub sckMultFrm_DataArrival(ByVal bytesTotal As Long)
Dim frmrevHead As Variant
b = b + 1 ‘b用于計算幀數(shù)
lenByte = 649 * b – 1 ‘計算接收數(shù)據(jù)的總字節(jié)數(shù)
sckMultFrm.GetData frmrevHead ‘接收單幀數(shù)據(jù)
ReDim Preserve revHead(0 To lenByte)‘定義動態(tài)數(shù)組存放接收到的所有數(shù)據(jù)
For j = 0 To 648
revHead(a) = frmrevHead(j)
a = a + 1 ‘a(chǎn)用于累計數(shù)據(jù)字節(jié)數(shù),將每幀收到的變體型數(shù)組元素放到一個數(shù)組中
Next
End Sub
3 用Timer控件實現(xiàn)多幀的接收
由于只要數(shù)據(jù)緩沖區(qū)有數(shù)據(jù),Winsock控件就會觸發(fā)DataArrival事件,并且把接收到的數(shù)據(jù)存入一個變體型變量中,而我們的下位機每上傳一幀數(shù)據(jù)的間隔時間是毫秒級的,上位機軟件還來不及處理完第一幀數(shù)據(jù),第二幀數(shù)據(jù)又來了,這樣使用一個變量來接收數(shù)據(jù)就有點力不從心,而且會發(fā)生丟數(shù)據(jù)的情況,為了解決這種矛盾,我們想到了利用Timer控件來控制處理接收數(shù)據(jù)的時間。
首先我們設(shè)置一個計時器控件Timer1,用它來處理接收到的第一幀數(shù)據(jù),在它的Timer事件中獲取表示總幀數(shù)的那個字節(jié)的數(shù)據(jù),根據(jù)該字節(jié)的幀數(shù)我們再來設(shè)置Timer2的Interval(時間間隔)屬性,該屬性控制當(dāng)全部消費機數(shù)據(jù)(所有幀)傳輸完畢后觸發(fā)Timer事件的時間,在此事件中對全部接收到的數(shù)據(jù)進行處理。
Private Sub Timer1_Timer()
Timer1.Interval = 0
intfrmcount = revHead(6) ‘讀取總幀數(shù)字節(jié)(據(jù)自定義協(xié)議而定),幀數(shù)從0開始記數(shù)
If intfrmcount = 0 Then ‘為0表示只有一幀,則Timer2不用等待
Timer2.Interval = 10 ‘只需10mS就可以處理已收到的第一幀數(shù)據(jù)了
Else
Timer2.Interval = intfrmcount * 1000 ‘若幀數(shù)不為0,則延長Timer2的等待時間
End If
End Sub
當(dāng)全部幀都存入到動態(tài)數(shù)組revHead()中后,就可在Timer2控件的Timer事件中來處理下位機上傳的所有的數(shù)據(jù)。
Private Sub Timer2_Timer()
Dim count As Integer
Timer2.Interval = 0
count = (intfrmcount + 1) * 649 - 1
For i = 0 To count
Text2 = Text2 & Hex(revHead(i)) & ";"
Next
StatusBar1.Panels(1).Text = "數(shù)據(jù)接收完畢,正在將數(shù)據(jù)添加至數(shù)據(jù)庫,請等待……"
…… '處理收到的數(shù)據(jù)
End Sub
4 結(jié)束語
在Text2文本框中可以看到收到的全部數(shù)據(jù),事后可對數(shù)據(jù)進行分析,例如根據(jù)協(xié)議提取需要的數(shù)據(jù)存入后臺數(shù)據(jù)庫等。這種方法雖然很簡便的實現(xiàn)了上位機接收并處理多幀數(shù)據(jù)的功能,但它仍有不足之處。例如在程序中,我們設(shè)置接收第一幀的并處理的時間為2000毫秒(即2秒鐘),但如果由于網(wǎng)絡(luò)傳輸原因,導(dǎo)致2秒鐘傳送不完一幀數(shù)據(jù)時,會出現(xiàn)丟失數(shù)據(jù)的錯誤,因此根據(jù)下位機的數(shù)據(jù)傳輸和處理的時間來很好控制Timer控件的間隔時間是關(guān)鍵,這方面還需改進。
參考文獻:
[1] 高春艷,劉彬彬.Visual Basic控件參考大全[M]北京:人民郵電出版社,2006.12.
[2] 崔彥鋒,許小榮.VB 網(wǎng)絡(luò)與遠(yuǎn)程控制編程實例教程[M]北京:北京希望電子出版社,2002.
[3] 楊延雙,張建標(biāo),王全民.TCP/IP協(xié)議分析及應(yīng)用[M]北京:機械工業(yè)出版社,2006.
[4] 汪曉平.Visual Basic網(wǎng)絡(luò)高級編程[M].北京:人民郵電出版社,2001.
收稿日期:2008-04-17
作者簡介:郭毅(1979-),男,湖北黃石人,海南政法職業(yè)學(xué)院助教,研究方向為計算機應(yīng)用;涂婧璐(1977-),女,江西撫州人,海南政法職業(yè)學(xué)院助教,工學(xué)碩士,研究方向為計算機通信及圖形圖像學(xué)。