VB中基于TCPIP協(xié)議的點(diǎn)對(duì)點(diǎn)文件傳輸_第1頁(yè)
VB中基于TCPIP協(xié)議的點(diǎn)對(duì)點(diǎn)文件傳輸_第2頁(yè)
VB中基于TCPIP協(xié)議的點(diǎn)對(duì)點(diǎn)文件傳輸_第3頁(yè)
VB中基于TCPIP協(xié)議的點(diǎn)對(duì)點(diǎn)文件傳輸_第4頁(yè)
VB中基于TCPIP協(xié)議的點(diǎn)對(duì)點(diǎn)文件傳輸_第5頁(yè)
已閱讀5頁(yè),還剩4頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、vb中基于tcp/ip協(xié)議的點(diǎn)對(duì)點(diǎn)文件傳輸葛斌 摘 要 隨著網(wǎng)絡(luò)的普及,網(wǎng)絡(luò)編程顯得尤其重要。本文使用winsock控件實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)間的文件傳輸,描述了winsock控件的使用方法及有關(guān)文件傳輸?shù)乃惴ā?關(guān)鍵詞 tcp/ip協(xié)議,winsock控件,網(wǎng)絡(luò)編程,文件傳輸,斷點(diǎn)續(xù)傳。 隨著計(jì)算機(jī)網(wǎng)絡(luò)的迅速發(fā)展,人們的生活越來越離不開網(wǎng)絡(luò),如今網(wǎng)絡(luò)編程已成為計(jì)算機(jī)發(fā)展的熱點(diǎn),而在眾多的網(wǎng)絡(luò)通信中,又以tcp/ip協(xié)議最為流行。本文討論的winsock控件,提供了訪問tcp/ip網(wǎng)絡(luò)的捷徑,使用它可以不必了解tcp/ip的細(xì)節(jié)和調(diào)用winsock api,只要設(shè)置好相應(yīng)的屬性和觸發(fā)事件后的處理,就可

2、以實(shí)現(xiàn)計(jì)算機(jī)之間的數(shù)據(jù)通信。一、winsock控件 winsock即windows sockets規(guī)范的簡(jiǎn)稱,是目前最流行的網(wǎng)絡(luò)通信應(yīng)用程序接口之一。所謂socket,通常也稱作套接字,用于描述ip地址和端口,是一個(gè)通信鏈的句柄。應(yīng)用程序通常通過“套接字”向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求。socket是網(wǎng)絡(luò)上運(yùn)行的兩個(gè)程序間雙向通訊的一端,它既可以接受請(qǐng)求,也可以發(fā)送請(qǐng)求,利用它可以較為方便的編寫網(wǎng)絡(luò)上數(shù)據(jù)的傳遞。winsock控件工作在傳輸層上,在這一層上,目前主要流行的協(xié)議包括tcp和udp兩種:tcp協(xié)議適用于那些對(duì)于數(shù)據(jù)的可靠性要求比較高的情況,目前大多數(shù)的網(wǎng)絡(luò)應(yīng)用層協(xié)議都是基于tcp協(xié)

3、議的(例如常用的http、ftp、smtp、pop3等協(xié)議);udp協(xié)議適用于對(duì)數(shù)據(jù)可靠性要求不高而對(duì)速度要求較高的情況,這里主要包括一些需要大流量的(例如real公司的rtsp協(xié)議,騰訊公司的qq協(xié)議等)。二、winsock控件通信的工作原理 winsock控件是基于socket規(guī)范創(chuàng)建的,所以其通信的實(shí)質(zhì)是對(duì)socket接口進(jìn)行數(shù)據(jù)的讀寫操作。如果兩個(gè)應(yīng)用程序需要通信,它們可以通過使用socket類來建立套接字連接,可以將這個(gè)過程想象為一次電話呼叫過程:呼叫者通過撥號(hào)與被呼叫者連接,當(dāng)電話接通時(shí),雙方都可以自由通話了,只不過這里的呼叫者被稱為“客戶”,被呼叫者則稱為“服務(wù)器”,而號(hào)碼則為“

4、ip地址+端口”,但在建立連接之前,必須由“客戶”發(fā)出呼叫,且此時(shí)的“服務(wù)器”正在監(jiān)聽。因此,基于tcp/ip協(xié)議的通信,需要分別建立客戶端應(yīng)用程序和服務(wù)器端應(yīng)用程序。其大致流程如圖1所示: 圖1 winsock工作原理 端口號(hào)被規(guī)定在065535范圍內(nèi)的某一個(gè)整數(shù),其中01023被預(yù)先定義的服務(wù)器通信所占用(如telnet占用23,http占用端口80),所以最好使用102465535這些端口中的某一個(gè),以免發(fā)生端口沖突。三、基本方法 客戶端要與服務(wù)器端進(jìn)行通信,首先,必須知道服務(wù)器端的域名或ip地址(remotehost屬性),就像要和某人打電話前,必須知道對(duì)方的電話號(hào)碼;其次,還必須和服

5、務(wù)器端約定相同的端口(remoteport屬性),用于數(shù)據(jù)的輸入和輸出;最后,調(diào)用connect方法與服務(wù)器端建立連接。 服務(wù)器端應(yīng)設(shè)置一個(gè)監(jiān)聽端口(localport屬性),端口應(yīng)與客戶端的端口相同,同時(shí)調(diào)用listen方法時(shí)刻監(jiān)聽客戶端的連接請(qǐng)求(connectionrequest事件);當(dāng)接收到客戶端的連接請(qǐng)求時(shí),可調(diào)用connectionrequest事件的accept方法,這樣與客戶端的連接就建立了。 客戶端和服務(wù)器端成功建立連接后,任何一方都可以自由的發(fā)送數(shù)據(jù)(senddata方法)和接收數(shù)據(jù)(getdata方法),這些方法都在dataarrival事件中。四、案例實(shí)現(xiàn) 這里筆者通

6、過一個(gè)實(shí)際應(yīng)用,來說明如何使用winsock控件進(jìn)行網(wǎng)絡(luò)通信。實(shí)例中有兩臺(tái)計(jì)算機(jī),一臺(tái)作為服務(wù)器端,一臺(tái)作為客戶端,實(shí)現(xiàn)的功能是將服務(wù)器端的某一文件傳送到客戶端,服務(wù)器端和客戶端進(jìn)行點(diǎn)對(duì)點(diǎn)的文件傳輸。 1.實(shí)現(xiàn)原理 本文將實(shí)現(xiàn)的文件傳輸只有一個(gè)發(fā)送方和一個(gè)接收方,這是最基本的文件傳輸方式,運(yùn)用的原理也比較簡(jiǎn)單:發(fā)送方先獲取待傳輸文件的基本信息,主要是文件名及文件長(zhǎng)度(用于創(chuàng)建數(shù)據(jù)緩沖區(qū));然后,將其發(fā)送給接收方;接著,建立和文件一樣大小的數(shù)據(jù)緩沖區(qū),并將文件讀入;最后,將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)發(fā)送給接收方。與此同時(shí),當(dāng)接收方接收到文件名和文件長(zhǎng)度之后,就為其創(chuàng)建新的文件和數(shù)據(jù)緩沖區(qū);然后,接收傳輸

7、的文件數(shù)據(jù),并將其放在數(shù)據(jù)緩沖區(qū)中;最后,依次將數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)寫入新創(chuàng)建的文件中。這樣便完成了不同計(jì)算機(jī)之間的文件傳輸。 2.服務(wù)器端主程序代碼 “通用”中聲明如下:option base 1dim data() as byte, send as long 聲明數(shù)據(jù)緩沖區(qū)和已傳輸?shù)臄?shù)據(jù)dim filepath as string, filename as string, filelength as long 存儲(chǔ)文件信息發(fā)送文件名和文件長(zhǎng)度代碼:winsock1.senddata filenamewinsock1.senddata filelength發(fā)送文件按鈕事件的代碼:private

8、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 filelengthget #1, j, data(j)next更新發(fā)送的數(shù)據(jù)send = filelength發(fā)送數(shù)據(jù)winsock1.senddata dataclose #1end sub開啟按鈕事件的代碼:private sub start_click()winsock1.protocol = scktcpprot

9、ocol 以tcp方式進(jìn)行通信設(shè)置服務(wù)器通信程序的端口號(hào),這里筆者使用的端口是8080winsock1.localport = val(porttext.text)winsock1.listen 等待客戶端連接請(qǐng)求狀態(tài)欄顯示提示文字statusbar1.simpletext = 服務(wù)器已工作,準(zhǔn)備接受請(qǐng)求end sub客戶端請(qǐng)求連接事件代碼:private sub winsock1_connectionrequest(byval requestid as long)如果當(dāng)前連接是打開的,則關(guān)閉if winsock1.state 0 thenwinsock1.closeend ifwinsock

10、1.accept requestid 接受客戶請(qǐng)求statusbar1.simpletext = 有客戶請(qǐng)求,建立連接。end sub 運(yùn)行結(jié)果如圖2所示:圖2 服務(wù)器端運(yùn)行效果 3.客戶端主程序代碼 “通用”中聲明如下:option base 1dim flag as boolean 設(shè)置開關(guān)dim filename as string, filelength as long 存儲(chǔ)文件信息dim data() as byte, received as long 聲明數(shù)據(jù)緩沖區(qū)和已接收的數(shù)據(jù)初始化開關(guān)private sub form_load()flag = trueend sub連接按鈕事件

11、的代碼:private sub connect_click()winsock1.protocol = scktcpprotocol 以tcp方式進(jìn)行通信設(shè)置遠(yuǎn)程服務(wù)器ip地址,為方便調(diào)試筆者使用的是自身的ip地址winsock1.remotehost = hosttext.text設(shè)置遠(yuǎn)程服務(wù)器通信程序端口號(hào),與服務(wù)器端相同winsock1.remoteport = val(porttext.text)winsock1.connect 與服務(wù)器端建立連接end sub數(shù)據(jù)到達(dá)事件的代碼:private sub winsock1_dataarrival(byval bytestotal as l

12、ong)狀態(tài)欄顯示提示文字statusbar1.simpletext = 正在接收服務(wù)器發(fā)送的數(shù)據(jù).先接收文件名和文件的長(zhǎng)度if flag = true thenwinsock1.getdata filename, vbstring, bytestotal - 4winsock1.getdata filelength, vblong建立文件open filename for binary as #1flag = falseelse設(shè)置緩沖區(qū)redim data(bytestotal)接收數(shù)據(jù)并寫入文件winsock1.getdata data, vbarray + vbbytefor j =

13、received + 1 to received + bytestotalput #1, j, data(j - received - 1)next更新接收到的數(shù)據(jù)received = received + bytestotalprogressbar1.value = int(received / filelength) * 100)if progressbar1.value = 100 then close #1end ifend sub 運(yùn)行結(jié)果如圖3所示: 圖3 客戶端運(yùn)行效果 從以上的實(shí)例中,基本了解了有關(guān)winsock 控件的使用方法和文件傳輸?shù)倪^程。然而,當(dāng)需要傳送的數(shù)據(jù)比較大時(shí),

14、就不能像以上介紹的那樣,直接將整個(gè)文件放入數(shù)據(jù)緩沖區(qū)中了,我們的內(nèi)存是無法忍受用一個(gè)幾百mb甚至上gb的空間去存儲(chǔ)那些臨時(shí)數(shù)據(jù)的。顯然,這種做法已遠(yuǎn)不能滿足我們的需求,這時(shí)可以將文件按照一定的大小,分成若干個(gè)數(shù)據(jù)包(遠(yuǎn)小于內(nèi)存的容量)。首先,設(shè)置數(shù)據(jù)包的大?。ㄈ?4k),根據(jù)文件的基本信息(主要文件的長(zhǎng)度),計(jì)算出總共需要的數(shù)據(jù)包數(shù);然后,依次讀取同數(shù)據(jù)包一樣大小的數(shù)據(jù)到數(shù)據(jù)緩沖區(qū)中;接著,將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù),發(fā)送到指定的計(jì)算機(jī)上;同時(shí)在另一端,建立一個(gè)數(shù)據(jù)緩沖區(qū),緩沖區(qū)的大小要根據(jù)接收到的數(shù)據(jù)來確定,依次接收客戶端傳輸過來的數(shù)據(jù)包,并將數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)寫入相應(yīng)的文件中,這樣就很容易實(shí)現(xiàn)大文

15、件的傳輸了。 但還有些時(shí)候,當(dāng)我們?cè)趥鬏斘募倪^程中,突然被意外中斷,導(dǎo)致網(wǎng)絡(luò)連接中斷。這時(shí),我們又不得不再次將文件重新傳輸一次,顯然這浪費(fèi)了不少的時(shí)間,那怎樣解決這類問題呢?這就涉及到斷點(diǎn)續(xù)傳了,即我們可以接著上次未傳輸完的地方,繼續(xù)傳輸文件。 斷點(diǎn)續(xù)傳的方法有多種,比較常見的一種是通過設(shè)置一個(gè)臨時(shí)文件,記錄已經(jīng)傳輸?shù)奈募畔?,?dāng)傳輸文件中斷時(shí),可以通過臨時(shí)文件的數(shù)據(jù)來推算出未傳輸?shù)臄?shù)據(jù);然后,在每次進(jìn)行文件傳輸前,都先查找文件是否有臨時(shí)文件,并將此信息傳輸給服務(wù)器端,于是服務(wù)器端可據(jù)此再接著進(jìn)行傳輸剩余的數(shù)據(jù),當(dāng)文件全部傳輸完畢時(shí),刪除臨時(shí)文件,這樣就實(shí)現(xiàn)了斷點(diǎn)續(xù)傳。這里筆者依然通過上面的

16、那個(gè)實(shí)例,來說明如何在vb中使用winsock控件實(shí)現(xiàn)文件的分塊傳輸和斷點(diǎn)續(xù)傳。 4.服務(wù)器端主程序如下 “通用”中聲明如下:option base 1const packsize as long = 65536 每包大小為64kdim filepath as string, filename as string, filelength as long 存儲(chǔ)文件信息dim data() as byte, pack as long, send as long 數(shù)據(jù)緩沖區(qū),文件包數(shù),已傳輸?shù)臄?shù)據(jù)“發(fā)送文件”按鈕事件代碼:private sub sendfile_click()statusbar1.

17、simpletext = 向客戶端發(fā)送數(shù)據(jù)計(jì)算需要傳輸文件的包數(shù)pack = (filelength - send) packsizeif (filelength - send) mod packsize) 0 then pack = pack + 1if pack = 0 then pack = pack + 1傳輸文件open filepath for binary as #1for i = 1 to pack如果只有一包if pack = 1 thenredim data(filelength - send)讀取數(shù)據(jù)for j = send + 1 to filelengthget #1

18、, 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 - sendget #1, send + j, data(j)next發(fā)送文件數(shù)據(jù)winsock1.senddata data更新已傳輸文件的數(shù)據(jù)send = filelengthexit forelse將文件數(shù)據(jù)放到數(shù)據(jù)緩沖區(qū)redim data(pack

19、size)for j = 1 to packsizeget #1, send + j, data(j)next發(fā)送文件數(shù)據(jù)winsock1.senddata data更新已傳輸文件的數(shù)據(jù)send = send + packsizeend ifprogressbar1.value = int(send / filelength) * 100)nextprogressbar1.value = int(send / filelength) * 100)close #1end sub返回客戶端已接收文件的數(shù)據(jù)private sub winsock1_dataarrival(byval bytestot

20、al as long)winsock1.getdata send, vblongend sub 運(yùn)行效果如圖4所示: 圖4 服務(wù)器端斷點(diǎn)續(xù)傳的運(yùn)行效果 5.客戶端主程序如下 數(shù)據(jù)到達(dá)事件的代碼:private sub winsock1_dataarrival(byval bytestotal as long)statusbar1.simpletext = 正在接收服務(wù)器的數(shù)據(jù).if sign = true then分別接收傳輸文件的文件名、文件長(zhǎng)度winsock1.getdata filename, vbstring, bytestotal - 4winsock1.getdata filelength, vblong為傳輸文件設(shè)置臨時(shí)文件tempfile = filename + .td返回已接收的數(shù)據(jù)open filename for binary as #1open tempfile for binary as #2if lof(2) 0 theninput #2, recei

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論