VB SOCKET 实现文件资料传输Word文件下载.docx
- 文档编号:14968057
- 上传时间:2022-10-26
- 格式:DOCX
- 页数:10
- 大小:18.23KB
VB SOCKET 实现文件资料传输Word文件下载.docx
《VB SOCKET 实现文件资料传输Word文件下载.docx》由会员分享,可在线阅读,更多相关《VB SOCKET 实现文件资料传输Word文件下载.docx(10页珍藏版)》请在冰豆网上搜索。
其实,情况没有那么悲观,我们完全可以使用数组来解决这个问题,就是使用byte数组。
把要传送的文件都读到数组里,然后发送出去。
程序如下:
FileName为要传送的文件名,WinS为发送文件的WinSock控件。
这是一个发送端的程序。
PublicSubSendFile(FileNameAsString,WinSAsWinsock)DimFreeFAsInteger'
空闲的文件号DimLenFileAsLong'
文件的长度DimbytData()AsByte'
存放数据的数组FreeF=FreeFile'
获得空闲的文件号OpenFileNameForBinaryAs#FreeFile'
打开文件DoEventsLenFile=LOF(FreeF)'
获得文件长度ReDimbytData(1ToLenFile)'
根据文件长度重新定义数组大小Get#FreeF,,bytData'
把文件读入到数组里Close#FreeF'
关闭文件WinS.SendDatabytData'
发送数据EndSub承受端的程序如下:
PrivateSubWinsock1_DataArrival(ByValbytesTotalAsLong)DimbytData()AsByteDimff=FreeFileOpenstrFileNameForBinaryAs#fReDimbytData(1TobytesTotal)Winsock1.GetDatabytDataPut#f,i,bytDatai=i+bytesTotal'
保证每次写都是在文件的末尾,i是个全局变量Close#fEndSub这里有两个需要注意的地方,ReDimPreservebytData(1ToLenFile),下标是从1开始的,如果你写成ReDimbytData(LenFile),下标就是从0开始了,数组就有LenFile+1长了。
LenFile=LOF(FreeFile)中的LOF是获得文件长度的函数,是VB里带的,我见过很多例子用API,或者循环的读直到末尾来获取文件长度,这样都是很麻烦的,使用LOF函数就可以了。
这样的程序,即可以传送文本文件,也可以传送二进制文件。
但是你有没有发现这个程序的问题呢?
如果我要传送一个50M的文件呢?
系统可以为bytData分配50M的内存空间吗?
于是笔者拿一个50M的文件做实验吧,接收到的文件和原来的文件不一样,比原来的大。
问题出在那呢?
首先,根据文件大小重新定义bytData数组的大小本身就有问题,系统是不可能无限制的给数组分配空间的,即使可以,也会造成系统响应变慢。
在传50M文件的时候,系统就跟死机了一样。
那么怎么解决这个问题呢,一个自然的想法就是把数据分段传送。
发送程序,iPos是个全局变量,初始值为0。
这个变量保存着当前数据的位置。
ConstiMax=65535是每个数据块的大小。
dimiposaslongConstiMax=65535DimFreeFAsInteger'
获得空闲的文件号OpenFileNameForBinaryAs#FreeF'
获得文件长度IfLenFile<
=iMaxThen'
如果要发送的文件小于数据块大小,直接发送ReDimbytData(1ToLenFile)'
发送数据ExitSubEndIf'
文件大于数据块大小,进展分块发送DoUntil(iPos>
=(LenFile-iMax))'
发送整块数据的循环ReDimbytData(1ToiMax)Get#FreeF,iPos+1,bytDataWinS.SendDatabytDataiPos=iPos+iMax'
移动iPos,使它指向下来要读的数据Loop'
这里要注意的是,必须检查文件有没有剩下的数据,如果文件大小正好等于数据块大小的'
整数倍,那么就没有剩下的数据了ReDimbytData(1ToLenFile-iPos)'
发送剩下的不够一个数据块的数据Get#FreeF,iPos+1,bytDataWinS.SendDatabytDataClose#FreeF下面是接收端的程序:
PrivateSubWinsock1_DataArrival(ByValbytesTotalAsLong)DimbytData()AsByteDimlLenFileAsLongDimff=FreeFileOpenstrFileNameForBinaryAs#f'
strFileName是文件名lLenFile=LOF(f)ReDimbytData(1TobytesTotal)Winsock1.GetDatabytDataIflLenFile=0Then'
lLenFile=0表示是第一次打开文件,这里有个问题,就是'
如果如果该文件存在的话,就会出错,应该在打开前检查文件是否存在。
〔这里我省略了〕Put#f,1,bytDataElsePut#f,lLenFile+1,bytDataEndIfClose#fEndSub
VBSOCKET实现文件传输支持断点续传
OptionExplicit
ConstPACKSIZEAsLong=65536'
每包大小为64K
PrivatefilepathAsString
PrivatefilenameAsString
PrivatefilelengthAsLong'
存储文件信息
Privatedata()AsByte
PrivatepackAsLong
PrivatesendedDataAsLong'
数据缓冲区,文件包数,已传输的数据
PrivatealreadySendAsBoolean
PrivatecmsStrAsString
ConstfileDAsString="
D:
\NMSPlugin\source\LanBus.rar"
PrivateSubcmdConnectClient_Click()
WinsockSend.Protocol=sckTCPProtocol
WinsockSend.RemoteHost="
127.0.0.1"
WinsockSend.RemotePort=8080
WinsockSend.Connect'
连接客户端
EndSub
PrivateSubcmdSendFile_Click()
OpenfileDForBinaryAs#3
filename="
LanBus.rar"
filelength=LOF(3)
Close#3
WinsockSend.SendData("
NMSP_AYUREADY"
)
PrivateSubWinsockSend_Connect()
StatusBar1.Caption="
已与客户端建立连接。
"
'
发送文件"
按钮事件代码:
PrivateSubsendFile()
DimiAsInteger
DimjAsLong
DimmAsLong
filepath=fileD
向客户端传送文件:
&
filename&
"
大小为:
filelength
'
计算需要传输文件的包数
pack=(filelength-sendedData)\PACKSIZE
If((filelength-sendedData)ModPACKSIZE)<
>
0Then
pack=pack+1
EndIf
Ifpack=0Then
传输文件
OpenfilepathForBinaryAs#1
Fori=1Topack
如果只有一包
Ifpack=1Then
Debug.Print"
filename="
|filelength="
filelength&
|send="
sendedData
ReDimdata(filelength-sendedData)
读取数据
Forj=sendedData+1Tofilelength
Get#1,j,data(j-sendedData)
Next
更新已传输文件的数据
sendedData=filelength
发送文件数据
WinsockSend.SendDatadata
如果是最后一包
ElseIfi+1=packThen
读取最后一包的数据
Forj=1Tofilelength-sendedData
Get#1,sendedData+j,data(j)
ExitFor
Else
将文件数据放到数据缓冲区
ReDimdata(PACKSIZE)
Form=1ToPACKSIZE
Get#1,sendedData+m,data(j)
sendedData=sendedData+PACKSIZE
End
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VB SOCKET 实现文件资料传输 实现 文件 资料 传输