VB中基于TCPIP協(xié)議的點對點文件傳輸
《VB中基于TCPIP協(xié)議的點對點文件傳輸》由會員分享,可在線閱讀,更多相關(guān)《VB中基于TCPIP協(xié)議的點對點文件傳輸(9頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、VB中基于TCP/IP協(xié)議的點對點文件傳輸 葛斌 摘 要 隨著網(wǎng)絡(luò)的普及,網(wǎng)絡(luò)編程顯得尤其重要。本文使用Winsock控件實現(xiàn)兩臺計算機間的文件傳輸,描述了Winsock控件的使用方法及有關(guān)文件傳輸?shù)乃惴ā? 關(guān)鍵詞 TCP/IP協(xié)議,Winsock控件,網(wǎng)絡(luò)編程,文件傳輸,斷點續(xù)傳。 隨著計算機網(wǎng)絡(luò)的迅速發(fā)展,人們的生活越來越離不開網(wǎng)絡(luò),如今網(wǎng)絡(luò)編程已成為計算機發(fā)展的熱點,而在眾多的網(wǎng)絡(luò)通信中,又以TCP/IP協(xié)議最為流行。本文討論的Winsock控件,提供了訪問TCP/IP網(wǎng)絡(luò)的捷徑,使用它可以不必了解TCP/IP的細節(jié)和調(diào)用Winsock API,只要設(shè)置好相應(yīng)的屬性
2、和觸發(fā)事件后的處理,就可以實現(xiàn)計算機之間的數(shù)據(jù)通信。 一、Winsock控件 Winsock即Windows Sockets規(guī)范的簡稱,是目前最流行的網(wǎng)絡(luò)通信應(yīng)用程序接口之一。所謂Socket,通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄。應(yīng)用程序通常通過“套接字”向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。Socket是網(wǎng)絡(luò)上運行的兩個程序間雙向通訊的一端,它既可以接受請求,也可以發(fā)送請求,利用它可以較為方便的編寫網(wǎng)絡(luò)上數(shù)據(jù)的傳遞。Winsock控件工作在傳輸層上,在這一層上,目前主要流行的協(xié)議包括TCP和UDP兩種:TCP協(xié)議適用于那些對于數(shù)據(jù)的可靠性要求比較高的情況,目前大
3、多數(shù)的網(wǎng)絡(luò)應(yīng)用層協(xié)議都是基于TCP協(xié)議的(例如常用的HTTP、FTP、SMTP、POP3等協(xié)議);UDP協(xié)議適用于對數(shù)據(jù)可靠性要求不高而對速度要求較高的情況,這里主要包括一些需要大流量的(例如Real公司的RTSP協(xié)議,騰訊公司的QQ協(xié)議等)。 二、Winsock控件通信的工作原理 Winsock控件是基于Socket規(guī)范創(chuàng)建的,所以其通信的實質(zhì)是對Socket接口進行數(shù)據(jù)的讀寫操作。如果兩個應(yīng)用程序需要通信,它們可以通過使用Socket類來建立套接字連接,可以將這個過程想象為一次電話呼叫過程:呼叫者通過撥號與被呼叫者連接,當電話接通時,雙方都可以自由通話了,只不過這里的呼叫者被稱為“客
4、戶”,被呼叫者則稱為“服務(wù)器”,而號碼則為“IP地址+端口”,但在建立連接之前,必須由“客戶”發(fā)出呼叫,且此時的“服務(wù)器”正在監(jiān)聽。因此,基于TCP/IP協(xié)議的通信,需要分別建立客戶端應(yīng)用程序和服務(wù)器端應(yīng)用程序。其大致流程如圖1所示: 圖1 Winsock工作原理 端口號被規(guī)定在0~65535范圍內(nèi)的某一個整數(shù),其中0~1023被預(yù)先定義的服務(wù)器通信所占用(如telnet占用23,http占用端口80),所以最好使用1024~65535這些端口中的某一個,以免發(fā)生端口沖突。 三、基本方法 客戶端要與服務(wù)器端進行通信,首先,必須知道服務(wù)器端的域名或IP地址(Remote
5、Host屬性),就像要和某人打電話前,必須知道對方的電話號碼;其次,還必須和服務(wù)器端約定相同的端口(RemotePort屬性),用于數(shù)據(jù)的輸入和輸出;最后,調(diào)用Connect方法與服務(wù)器端建立連接。 服務(wù)器端應(yīng)設(shè)置一個監(jiān)聽端口(LocalPort屬性),端口應(yīng)與客戶端的端口相同,同時調(diào)用Listen方法時刻監(jiān)聽客戶端的連接請求(ConnectionRequest事件);當接收到客戶端的連接請求時,可調(diào)用ConnectionRequest事件的Accept方法,這樣與客戶端的連接就建立了。 客戶端和服務(wù)器端成功建立連接后,任何一方都可以自由的發(fā)送數(shù)據(jù)(SendData方法)和接收數(shù)據(jù)(G
6、etData方法),這些方法都在DataArrival事件中。 四、案例實現(xiàn) 這里筆者通過一個實際應(yīng)用,來說明如何使用Winsock控件進行網(wǎng)絡(luò)通信。實例中有兩臺計算機,一臺作為服務(wù)器端,一臺作為客戶端,實現(xiàn)的功能是將服務(wù)器端的某一文件傳送到客戶端,服務(wù)器端和客戶端進行點對點的文件傳輸。 1.實現(xiàn)原理 本文將實現(xiàn)的文件傳輸只有一個發(fā)送方和一個接收方,這是最基本的文件傳輸方式,運用的原理也比較簡單:發(fā)送方先獲取待傳輸文件的基本信息,主要是文件名及文件長度(用于創(chuàng)建數(shù)據(jù)緩沖區(qū));然后,將其發(fā)送給接收方;接著,建立和文件一樣大小的數(shù)據(jù)緩沖區(qū),并將文件讀入;最后,將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)發(fā)送
7、給接收方。與此同時,當接收方接收到文件名和文件長度之后,就為其創(chuàng)建新的文件和數(shù)據(jù)緩沖區(qū);然后,接收傳輸?shù)奈募?shù)據(jù),并將其放在數(shù)據(jù)緩沖區(qū)中;最后,依次將數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)寫入新創(chuàng)建的文件中。這樣便完成了不同計算機之間的文件傳輸。 2.服務(wù)器端主程序代碼 “通用”中聲明如下: Option Base 1 Dim data() As Byte, send As Long 聲明數(shù)據(jù)緩沖區(qū)和已傳輸?shù)臄?shù)據(jù) Dim filepath As String, filename As String, filelength As Long 存儲文件信息 發(fā)送文件名和文件長度代碼: Winsock1.
8、SendData filename Winsock1.SendData filelength "發(fā)送文件"按鈕事件的代碼: Private Sub sendfile_Click() 狀態(tài)欄顯示提示文字 StatusBar1.SimpleText = "向客戶端發(fā)送數(shù)據(jù)..." Open filepath For Binary As #1 設(shè)置數(shù)據(jù)緩沖區(qū) ReDim data(filelength) 讀取數(shù)據(jù) For j = 1 To filelength Get #1, j, data(j) Next 更新發(fā)送的數(shù)據(jù) send = filelength 發(fā)送數(shù)據(jù)
9、 Winsock1.SendData data Close #1 End Sub "開啟"按鈕事件的代碼: Private Sub start_Click() Winsock1.Protocol = sckTCPProtocol 以TCP方式進行通信 設(shè)置服務(wù)器通信程序的端口號,這里筆者使用的端口是8080 Winsock1.LocalPort = Val(portText.Text) Winsock1.Listen 等待客戶端連接請求 狀態(tài)欄顯示提示文字 StatusBar1.SimpleText = "服務(wù)器已工作,準備接受請求…" End Sub "客戶端請求連接
10、"事件代碼: Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long) 如果當前連接是打開的,則關(guān)閉 If Winsock1.State <> 0 Then Winsock1.Close End If Winsock1.Accept requestID 接受客戶請求 StatusBar1.SimpleText = "有客戶請求,建立連接。" End Sub 運行結(jié)果如圖2所示: 圖2 服務(wù)器端運行效果 3.客戶端主程序代碼 “通用”中聲明如下: Option Base 1 Dim
11、 flag As Boolean 設(shè)置開關(guān) Dim filename As String, filelength As Long 存儲文件信息 Dim data() As Byte, received As Long 聲明數(shù)據(jù)緩沖區(qū)和已接收的數(shù)據(jù) 初始化開關(guān) Private Sub Form_Load() flag = True End Sub "連接"按鈕事件的代碼: Private Sub connect_Click() Winsock1.Protocol = sckTCPProtocol 以TCP方式進行通信 設(shè)置遠程服務(wù)器IP地址,為方便調(diào)試筆者使用的是自身的IP地
12、址 Winsock1.RemoteHost = hostText.Text 設(shè)置遠程服務(wù)器通信程序端口號,與服務(wù)器端相同 Winsock1.RemotePort = Val(portText.Text) Winsock1.connect 與服務(wù)器端建立連接 End Sub "數(shù)據(jù)到達"事件的代碼: Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) 狀態(tài)欄顯示提示文字 StatusBar1.SimpleText = "正在接收服務(wù)器發(fā)送的數(shù)據(jù)..." 先接收文件名和文件的長度 If flag = True
13、Then Winsock1.GetData filename, vbString, bytesTotal - 4 Winsock1.GetData filelength, vbLong 建立文件 Open filename For Binary As #1 flag = False Else 設(shè)置緩沖區(qū) ReDim data(bytesTotal) 接收數(shù)據(jù)并寫入文件 Winsock1.GetData data, vbArray + vbByte For j = received + 1 To received + bytesTotal Put #1, j, data(
14、j - received - 1) Next 更新接收到的數(shù)據(jù) received = received + bytesTotal ProgressBar1.Value = Int((received / filelength) * 100) If ProgressBar1.Value >= 100 Then Close #1 End If End Sub 運行結(jié)果如圖3所示: 圖3 客戶端運行效果 從以上的實例中,基本了解了有關(guān)Winsock 控件的使用方法和文件傳輸?shù)倪^程。然而,當需要傳送的數(shù)據(jù)比較大時,就不能像以上介紹的那樣,直接將整個文件放入數(shù)據(jù)緩沖
15、區(qū)中了,我們的內(nèi)存是無法忍受用一個幾百MB甚至上GB的空間去存儲那些臨時數(shù)據(jù)的。顯然,這種做法已遠不能滿足我們的需求,這時可以將文件按照一定的大小,分成若干個數(shù)據(jù)包(遠小于內(nèi)存的容量)。首先,設(shè)置數(shù)據(jù)包的大?。ㄈ?4K),根據(jù)文件的基本信息(主要文件的長度),計算出總共需要的數(shù)據(jù)包數(shù);然后,依次讀取同數(shù)據(jù)包一樣大小的數(shù)據(jù)到數(shù)據(jù)緩沖區(qū)中;接著,將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù),發(fā)送到指定的計算機上;同時在另一端,建立一個數(shù)據(jù)緩沖區(qū),緩沖區(qū)的大小要根據(jù)接收到的數(shù)據(jù)來確定,依次接收客戶端傳輸過來的數(shù)據(jù)包,并將數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)寫入相應(yīng)的文件中,這樣就很容易實現(xiàn)大文件的傳輸了。 但還有些時候,當我們在傳輸文件的
16、過程中,突然被意外中斷,導致網(wǎng)絡(luò)連接中斷。這時,我們又不得不再次將文件重新傳輸一次,顯然這浪費了不少的時間,那怎樣解決這類問題呢?這就涉及到"斷點續(xù)傳"了,即我們可以接著上次未傳輸完的地方,繼續(xù)傳輸文件。 "斷點續(xù)傳"的方法有多種,比較常見的一種是通過設(shè)置一個臨時文件,記錄已經(jīng)傳輸?shù)奈募畔?,當傳輸文件中斷時,可以通過臨時文件的數(shù)據(jù)來推算出未傳輸?shù)臄?shù)據(jù);然后,在每次進行文件傳輸前,都先查找文件是否有臨時文件,并將此信息傳輸給服務(wù)器端,于是服務(wù)器端可據(jù)此再接著進行傳輸剩余的數(shù)據(jù),當文件全部傳輸完畢時,刪除臨時文件,這樣就實現(xiàn)了"斷點續(xù)傳"。 這里筆者依然通過上面的那個實例,來說明如何在VB
17、中使用Winsock控件實現(xiàn)文件的分塊傳輸和斷點續(xù)傳。 4.服務(wù)器端主程序如下 “通用”中聲明如下: Option Base 1 Const PACKSIZE As Long = 65536 每包大小為64K Dim filepath As String, filename As String, filelength As Long 存儲文件信息 Dim data() As Byte, pack As Long, send As Long 數(shù)據(jù)緩沖區(qū),文件包數(shù),已傳輸?shù)臄?shù)據(jù) “發(fā)送文件”按鈕事件代碼: Private Sub sendfile_Click() Status
18、Bar1.SimpleText = "向客戶端發(fā)送數(shù)據(jù)…" 計算需要傳輸文件的包數(shù) pack = (filelength - send) \ PACKSIZE If ((filelength - send) Mod PACKSIZE) <> 0 Then pack = pack + 1 If pack = 0 Then pack = pack + 1 傳輸文件 Open filepath For Binary As #1 For i = 1 To pack 如果只有一包 If pack = 1 Then ReDim data(filelength - send) 讀取數(shù)據(jù)
19、 For j = send + 1 To filelength Get #1, j, data(j - send) Next 更新已傳輸文件的數(shù)據(jù) send = filelength 發(fā)送文件數(shù)據(jù) Winsock1.SendData data 如果是最后一包 ElseIf i + 1 = pack Then 讀取最后一包的數(shù)據(jù) ReDim data(filelength - send) For j = 1 To filelength - send Get #1, send + j, data(j) Next 發(fā)送文件數(shù)據(jù) Winsock1.SendData da
20、ta 更新已傳輸文件的數(shù)據(jù) send = filelength Exit For Else 將文件數(shù)據(jù)放到數(shù)據(jù)緩沖區(qū) ReDim data(PACKSIZE) For j = 1 To PACKSIZE Get #1, send + j, data(j) Next 發(fā)送文件數(shù)據(jù) Winsock1.SendData data 更新已傳輸文件的數(shù)據(jù) send = send + PACKSIZE End If ProgressBar1.Value = Int((send / filelength) * 100) Next ProgressBar1.Value = I
21、nt((send / filelength) * 100) Close #1 End Sub 返回客戶端已接收文件的數(shù)據(jù) Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Winsock1.GetData send, vbLong End Sub 運行效果如圖4所示: 圖4 服務(wù)器端斷點續(xù)傳的運行效果 5.客戶端主程序如下 "數(shù)據(jù)到達"事件的代碼: Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) StatusBar
22、1.SimpleText = "正在接收服務(wù)器的數(shù)據(jù)..." If sign = True Then 分別接收傳輸文件的文件名、文件長度 Winsock1.GetData filename, vbString, bytesTotal - 4 Winsock1.GetData filelength, vbLong 為傳輸文件設(shè)置臨時文件 tempfile = filename + ".td" 返回已接收的數(shù)據(jù) Open filename For Binary As #1 Open tempfile For Binary As #2 If LOF(2) > 0 Then In
23、put #2, received Winsock1.SendData received End If Close #2 sign = False Else Open tempfile For Output As #2 建立數(shù)據(jù)緩沖區(qū) ReDim data(bytesTotal) 接收服務(wù)器端傳輸?shù)臄?shù)據(jù) Winsock1.GetData data, vbArray + vbByte 將接收的數(shù)據(jù)寫入文件 For j = received + 1 To received + bytesTotal Put #1, j, data(j - received - 1) Nex
24、t 更新已接收的數(shù)據(jù) received = received + bytesTotal 更新臨時文件 Write #2, received ProgressBar1.Value = Int((received / filelength) * 100) 傳輸完畢 If ProgressBar1.Value >= 100 Then StatusBar1.SimpleText = "數(shù)據(jù)傳輸完畢!" Close #2 刪除臨時文件 Kill (tempfile) Close #1 End If Close #2 End If End Sub 運行效果如圖5所示: 圖5 客戶端斷點續(xù)傳的效果 五、結(jié)語 本文通過在VB中使用Winsock控件,實現(xiàn)網(wǎng)絡(luò)之間的文件傳輸,更進一步理解了其工作原理。此外,筆者還介紹了在網(wǎng)絡(luò)傳輸文件是要注意的問題,并對怎樣處理傳輸文件比較大時的情況進行了詳細的分析,并通過實際的方法實現(xiàn)了文件的“斷點續(xù)傳”,可以滿足實際中的要求,其設(shè)計的思想也具有普遍的通用性。
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 藥事管理與法規(guī)楊世民第2版第一章
- 初中語法-形容詞和副詞
- 《公民的基本權(quán)利和義務(wù)》人教部編版道德與法治課件
- 五年級上冊音樂課件-豐收的節(jié)日(2)|人音版(簡譜)最新
- 企業(yè)家商業(yè)計劃培訓教程75275
- 員工保密意識及技能教育培訓課件
- [精選]CAINA肖爾布拉克營銷戰(zhàn)略規(guī)劃(PPT 174頁)5799
- 教育專題:18___跨越百年的美麗
- 北魏孝文帝的改革措施
- 教育專題:兒童防拐教案1
- 數(shù)據(jù)隔離級別
- 最新2018清新簡約工作匯報模板【ppt精美模板】
- 電子工藝第5章(精品)
- [精選]中化公司銷售培訓77824
- (連云港專版)中考歷史復習 第2單元 中國近代史 第9課時 抗日戰(zhàn)爭和人民解放戰(zhàn)爭的勝利課件 北師大版