• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    VB中使用WinSock控件傳送文件

    發布: 2007-7-14 20:28 | 作者: 佚名    | 來源: 不詳     | 查看: 55次 | 進入軟件測試論壇討論

    領測軟件測試網

           傳送文件對于網絡編程來說是基本的功能,比如遠程控制軟件。在編制一個軟件時,我從網上下了很多傳文件的程序,這些程序提供的傳文件功能根本就不能用。傳文本還可以,傳二進制文件根本就不行。因此,作為一個基本的功能模塊,有必要單獨介紹一下。
        首先,在VB中要傳送字符串,你可以這樣寫:
    Dim strData As String
    strData = "Test"
    Winsock1.SendData strData
        但是如果你傳送的二進制文件,你還能用String變量來存放嗎?從理論上分析是不行的,我也做了實驗,確實是不行的。文件雖然可以傳,但是接受的文件和發送的不一樣,原因可能是二進制文件里可以有任何"字符",但是不是所有的字符都可以放在String變量里。
        除了String類型的變量,VB中其他類型的變量都只有幾個字節長,難道一次只能發幾個字節嗎?那樣豈不是要累死機器了!其實,情況沒有那么悲觀,我們完全可以使用數組來解決這個問題,就是使用byte數組。把要傳送的文件都讀到數組里,然后發送出去。程序如下:


    FileName 為要傳送的文件名,WinS為發送文件的WinSock控件。這是一個發送端的程序。
    Public Sub SendFile(FileName As String, WinS As Winsock)
    Dim FreeF As Integer '空閑的文件號
    Dim LenFile As Long '文件的長度
    Dim bytData() As Byte '存放數據的數組
    FreeF = FreeFile '獲得空閑的文件號
    Open FileName For Binary As #FreeFile '打開文件
    DoEvents

    LenFile = LOF(FreeFile) '獲得文件長度
    ReDim bytData(1 To LenFile) '根據文件長度重新定義數組大小
    Get #FreeFile, , bytData '把文件讀入到數組里
    Close #FreeFile '關閉文件
    WinS.SendData bytData '發送數據
    End Sub

        接受端的程序如下:

    Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
    Dim bytData() As Byte
    Dim f
    f = FreeFile
    Open strFileName For Binary As #f
    ReDim bytData(1 To bytesTotal)
    Winsock1.GetData bytData
    Put #f, i, bytData
    i = i + bytesTotal '保證每次寫都是在文件的末尾, i是個全局變量
    Close #f
    End Sub

        這里有兩個需要注意的地方,ReDim Preserve bytData(1 To LenFile),下標是從1開始的,如果你寫成ReDim bytData( LenFile),下標就是從0開始了,數組就有LenFile+1長了。LenFile = LOF(FreeFile)中的LOF是獲得文件長度的函數,是VB里帶的,我見過很多例子用API,或者循環的讀直到末尾來獲取文件長度,這樣都是很麻煩的,使用LOF函數就可以了。
        這樣的程序,即可以傳送文本文件,也可以傳送二進制文件。但是你有沒有發現這個程序的問題呢?如果我要傳送一個50M的文件呢?系統可以為bytData分配50M的內存空間嗎?
        于是筆者拿一個50M的文件做實驗吧,接收到的文件和原來的文件不一樣,比原來的大。問題出在那呢?
        首先,根據文件大小重新定義bytData數組的大小本身就有問題,系統是不可能無限制的給數組分配空間的,即使可以,也會造成系統響應變慢。在傳50M文件的時候,系統就跟死機了一樣。那么怎么解決這個問題呢,一個自然的想法就是把數據分段傳送。程序如下:
        發送程序, iPos是個全局變量,初始值為0。這個變量保存著當前數據的位置。Const iMax = 65535是每個數據塊的大小。


    Dim FreeF As Integer '空閑的文件號
    Dim LenFile As Long '文件的長度
    Dim bytData() As Byte '存放數據的數組
    FreeF = FreeFile '獲得空閑的文件號
    Open FileName For Binary As #FreeF '打開文件
    DoEvents
    LenFile = LOF(FreeF) '獲得文件長度
    If LenFile <= iMax Then '如果要發送的文件小于數據塊大小,直接發送
    ReDim bytData(1 To LenFile) '根據文件長度重新定義數組大小
    Get #FreeF, , bytData '把文件讀入到數組里
    Close #FreeF '關閉文件
    WinS.SendData bytData '發送數據
    Exit Sub
    End If
    '文件大于數據塊大小,進行分塊發送
    Do Until (iPos >= (LenFile - iMax)) '發送整塊數據的循環
    ReDim bytData(1 To iMax)
    Get #FreeF, iPos + 1, bytData
    WinS.SendData bytData
    iPos = iPos + iMax '移動iPos,使它指向下來要讀的數據
    Loop
    '這里要注意的是,必須檢查文件有沒有剩下的數據,如果文件大小正好等于數據塊大小的
    ' 整數倍,那么就沒有剩下的數據了
    ReDim bytData(1 To LenFile - iPos) '發送剩下的不夠一個數據塊的數據
    Get #FreeF, iPos + 1, bytData
    WinS.SendData bytData
    Close #FreeF

    下面是接收端的程序:
    Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
    Dim bytData() As Byte
    Dim lLenFile As Long
    Dim f
    f = FreeFile
    Open strFileName For Binary As #f 'strFileName是文件名
    lLenFile = LOF(f)
    ReDim bytData(1 To bytesTotal)
    Winsock1.GetData bytData
    If lLenFile = 0 Then 'lLenFile=0表示是第一次打開文件,這里有個問題,就是'如果如果該文件存在的話,就會出錯,應該在打開前檢查文件是否存在。(這里我省略了)
    Put #f, 1, bytData
    Else
    Put #f, lLenFile + 1, bytData
    End If
    Close #f
    End Sub

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>