首页 VBSOCKET实现文件传输

VBSOCKET实现文件传输

举报
开通vip

VBSOCKET实现文件传输LELEwasfinallyrevisedonthemorningofDecember16,2020VBSOCKET实现文件传输VB中使用WinSock控件传送文件传送文件对于网络编程来说是基本的功能,比如远程控制软件。在编制一个软件时,我从网上下了很多传文件的程序,这些程序提供的传文件功能根本就不能用。传文本还可以,传二进制文件根本就不行。因此,作为一个基本的功能模块,有必要单独介绍一下。首先,在VB中要传送字符串,你可以这样写:DimstrDataAsStringstrData="Test"但是如果你传送的二进...

VBSOCKET实现文件传输
LELEwasfinallyrevisedonthemorningofDecember16,2020VBSOCKET实现文件传输VB中使用WinSock控件传送文件传送文件对于网络编程来说是基本的功能,比如远程控制软件。在编制一个软件时,我从网上下了很多传文件的程序,这些程序提供的传文件功能根本就不能用。传文本还可以,传二进制文件根本就不行。因此,作为一个基本的功能模块,有必要单独介绍一下。首先,在VB中要传送字符串,你可以这样写:DimstrDataAsStringstrData="Test"但是如果你传送的二进制文件,你还能用String变量来存放吗?从理论上分析是不行的,我也做了实验,确实是不行的。文件虽然可以传,但是接受的文件和发送的不一样,原因可能是二进制文件里可以有任何"字符",但是不是所有的字符都可以放在String变量里。除了String类型的变量,VB中其他类型的变量都只有几个字节长,难道一次只能发几个字节吗?那样岂不是要累死机器了!其实,情况没有那么悲观,我们完全可以使用数组来解决这个问题,就是使用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'关闭文件'发送数据EndSub接受端的程序如下:PrivateSubWinsock1_DataArrival(ByValbytesTotalAsLong)DimbytData()AsByteDimff=FreeFileOpenstrFileNameForBinaryAs#fReDimbytData(1TobytesTotal)Put#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'空闲的文件号DimLenFileAsLong'文件的长度DimbytData()AsByte'存放数据的数组FreeF=FreeFile'获得空闲的文件号OpenFileNameForBinaryAs#FreeF'打开文件DoEventsLenFile=LOF(FreeF)'获得文件长度IfLenFile<=iMaxThen'如果要发送的文件小于数据块大小,直接发送ReDimbytData(1ToLenFile)'根据文件长度重新定义数组大小Get#FreeF,,bytData'把文件读入到数组里Close#FreeF'关闭文件'发送数据ExitSubEndIf'文件大于数据块大小,进行分块发送DoUntil(iPos>=(LenFile-iMax))'发送整块数据的循环ReDimbytData(1ToiMax)Get#FreeF,iPos+1,bytDataiPos=iPos+iMax'移动iPos,使它指向下来要读的数据Loop'这里要注意的是,必须检查文件有没有剩下的数据,如果文件大小正好等于数据块大小的'整数倍,那么就没有剩下的数据了ReDimbytData(1ToLenFile-iPos)'发送剩下的不够一个数据块的数据Get#FreeF,iPos+1,bytDataClose#FreeF下面是接收端的程序:PrivateSubWinsock1_DataArrival(ByValbytesTotalAsLong)DimbytData()AsByteDimlLenFileAsLongDimff=FreeFileOpenstrFileNameForBinaryAs#f'strFileName是文件名lLenFile=LOF(f)ReDimbytData(1TobytesTotal)IflLenFile=0Then'lLenFile=0 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示是第一次打开文件,这里有个问题,就是'如果如果该文件存在的话,就会出错,应该在打开前检查文件是否存在。(这里我省略了)Put#f,1,bytDataElsePut#f,lLenFile+1,bytDataEndIfClose#fEndSubVBSOCKET实现文件传输支持断点续传OptionExplicitConstPACKSIZEAsLong=65536'每包大小为64KPrivatefilepathAsStringPrivatefilenameAsStringPrivatefilelengthAsLong'存储文件信息Privatedata()AsBytePrivatepackAsLongPrivatesendedDataAsLong'数据缓冲区,文件包数,已传输的数据PrivatealreadySendAsBooleanPrivatecmsStrAsStringConstfileDAsString="D:\NMSPlugin\source\"PrivateSubcmdConnectClient_Click()=sckTCPProtocol==8080'连接客户端EndSubPrivateSubcmdSendFile_Click()OpenfileDForBinaryAs#3filename=""filelength=LOF(3)Close#3("NMSP_AYUREADY")EndSubPrivateSubWinsockSend_Connect()="已与客户端建立连接。"EndSub'"发送文件"按钮事件代码:PrivateSubsendFile()DimiAsIntegerDimjAsLongDimmAsLongfilepath=fileD="向客户端传送文件:"&filename&"大小为:"&filelength'计算需要传输文件的包数pack=(filelength-sendedData)\PACKSIZEIf((filelength-sendedData)ModPACKSIZE)<>0Thenpack=pack+1EndIfIfpack=0Thenpack=pack+1EndIf'传输文件OpenfilepathForBinaryAs#1Fori=1Topack'如果只有一包Ifpack=1Then"filename="&filename&"|filelength="&filelength&"|send="&sendedDataReDimdata(filelength-sendedData)'读取数据Forj=sendedData+1TofilelengthGet#1,j,data(j-sendedData)Next'更新已传输文件的数据sendedData=filelength'发送文件数据'如果是最后一包ElseIfi+1=packThen'读取最后一包的数据ReDimdata(filelength-sendedData)Forj=1Tofilelength-sendedDataGet#1,sendedData+j,data(j)Next'发送文件数据'更新已传输文件的数据sendedData=filelengthExitForElse'将文件数据放到数据缓冲区ReDimdata(PACKSIZE)Form=1ToPACKSIZEGet#1,sendedData+m,data(j)Next'发送文件数据'更新已传输文件的数据sendedData=sendedData+PACKSIZEEndIf=Int((sendedData/filelength)*100)Next=Int((sendedData/filelength)*100)Close#1alreadySend=FalseEndSub'客户端反馈PrivateSubWinsockSend_DataArrival(ByValbytesTotalAsLong)DimcmdStrAsString,vbStringIfMid(cmdStr,1,13)="NMSP_IAMREADY"Then'客户端已准备好接收时,要求客户端 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 已经接收的文件大小"NMSP_RPTCURLE"&filenameElseIfMid(cmdStr,1,13)="NMSP_REQFILEN"Then'客户端要求发送文件名称"NMSP_FILENAME="&filenameElseIfMid(cmdStr,1,13)="NMSP_REQFILES"Then'客户端要求发送文件大小"NMSP_FILESIZE="&filelength',vbLongElseIfMid(cmdStr,1,13)="NMSP_RECEIVED"Then'收到客户端已经接收到的文件大小报告"客户端已经接收了"&Mid(cmdStr,14,Len(cmdStr))sendedData=Mid(cmdStr,15,Len(cmdStr))Iffilelength=sendedDataThen"NMSP_SENDDONE"'初始化文件名,大小,已接收大小,遍历是否还需要向别的客户端发送Letfilename=""Letfilelength=0LetsendedData=0="文件发送完毕!"ElseCallsendFileEndIfEndIfEndSub'==========================================================客户端======================================================OptionExplicitDimflagAsBoolean'设置是否继续接收文件的开关标识PrivatereadyReceiveAsBooleanPrivatefilenameAsStringPrivatetempfileAsStringPrivaterealfileAsStringPrivatereveivePathAsStringPrivatefilelengthAsLong'存储文件信息Privatedata()AsByte,receivedAsLong'声明数据缓冲区和已接收的数据PrivateSubForm_Load()reveivePath=&"\received\"=sckTCPProtocol=8080CallinitReceiveStateEndSubPrivateSubWinsockReceive_Connect()="已经连接到服务器"EndSubPrivateSubWinsockReceive_ConnectionRequest(ByValrequestIDAsLong)<>0ThenEndIf="已接受连接请求。"EndSubPrivateSubWinsockReceive_DataArrival(ByValbytesTotalAsLong)DimjAsLong'分别接收传输文件的文件名、文件长度',vbString,bytesTotal-4',vbLong'判断指令类型IfreadyReceive=FalseThenDimcmdStrAsString,vbStringIfMid(cmdStr,1,13)="NMSP_AYUREADY"Then'询问是否准备好接收文件Iffilename=""Then("NMSP_REQFILEN")ElseIffilelength=0Then("NMSP_REQFILES")Else("NMSP_IAMREADY")EndIfElseIfMid(cmdStr,1,13)="NMSP_FILENAME"Then'文件名filename=Mid(cmdStr,15,Len(cmdStr))("NMSP_REQFILES")ElseIfMid(cmdStr,1,13)="NMSP_FILESIZE"Then'文件大小filelength=Mid(cmdStr,15,Len(cmdStr))If(filelength<>0)Then("NMSP_IAMREADY")EndIfElseIfMid(cmdStr,1,13)="NMSP_RPTCURLE"Then'服务器端要求提供已经接收的文件大小'为传输文件设置临时文件realfile=reveivePath&filenametempfile=reveivePath&filename&".td"'返回已接收的数据'OpenrealfileForBinaryAs#1OpentempfileForBinaryAs#2IfLOF(2)>0ThenInput#2,received"received="&receivedEndIfClose#2"NMSP_RECEIVED="&receivedreadyReceive=True="准备接收文件:"&filename&"大小为:"&filelengthElseIfMid(cmdStr,1,14)="NMSP_SENDDONE="Then'服务器发送文件完毕执行安装操作EndIfElserealfile=reveivePath&filenametempfile=reveivePath&filename&".td"="正在接收文件:"&filename&"保存到:"&realfile'返回已接收的数据OpenrealfileForBinaryAs#1OpentempfileForBinaryAs#2'建立数据缓冲区ReDimdata(bytesTotal)'接收服务器端传输的数据,vbArray+vbByte'将接收的数据写入文件Forj=received+1Toreceived+bytesTotalPut#1,j,data(j-received-1)Put#2,j,data(j-received-1)Next'更新已接收的数据received=received+bytesTotal'更新临时文件'Write#2,received=Int((received/filelength)*100)'传输完毕>=100Then="数据传输完毕!"Close#2'删除临时文件Kill(tempfile)Close#1CallinitReceiveStateEndIfClose#1Close#2EndIfEndSubPrivateSubinitReceiveState()readyReceive=Falsereceived=0filelength=0filename=""="监听中"EndSub
本文档为【VBSOCKET实现文件传输】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
曾茜996
暂无简介~
格式:doc
大小:2MB
软件:Word
页数:10
分类:企业经营
上传时间:2022-05-05
浏览量:1