利用Winsock下载文件.docx
《利用Winsock下载文件.docx》由会员分享,可在线阅读,更多相关《利用Winsock下载文件.docx(16页珍藏版)》请在冰豆网上搜索。
利用Winsock下载文件
利用Winsock下载文件(支持断点续传)-数据库专栏,SQLServer
作者:
网友供稿点击:
6
推荐西部数码-全国虚拟主机10强!
20余项虚拟主机管理功能,全国领先!
第6代双线路虚拟主机,南北访问畅通无阻!
可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!
P4主机租用799元/月.月付免压金
站内搜索
按标题搜索按内容搜索
文章页数:
[1]
第一步,建立工程,引用winsock(visualbasic最好打sp6,否则ms有一个bug),在此省略
第二步,具体实现代码步骤1:
发送请求
说明:
(1)这里简单采用了判断是否已经有同名文件表示是否要断点续传
(2)下载的地址,大小和已下载字节数也只是简单地存在ini文件中,更安全的做法本文不作讨论
有兴趣的朋友可以联系我
--------------------------------------------------------------------------------
name:
downloadfile
author:
reker2004/3/20
desc:
连接远端主机,发送接收文件请求,等待远端主机响应
params:
none
history:
none
--------------------------------------------------------------------------------
privatesubdownloadfile()
onerrorresumenext
starttime=time()
withwinsck
.remotehost=host远端主机地址
.remoteport=80
.connect
等待服务器连接相应
dowhile.state<>sckconnected
doevents:
doevents:
doevents:
doevents
20秒超时
ifdatediff("s",starttime,time())>20then
showinfo"连接超时"
.close
exitsub
endif
loop
发送下载文件请求
此处使用http/1.0协议
strcommand="get"+updateurl+"http/1.0"+vbcrlf下载地址
strcommand=strcommand+"accept:
*/*"+vbcrlf这句可以不要
strcommand=strcommand+"accept:
text/html"+vbcrlf这句可以不要
strcommand=strcommand+vbcrlf
strcommand=strcommand&"host:
"&host&vbcrlf
ifdir(savefilename)<>""then是否已经存在下载文件
dimconfirm
confirm=msgbox("已经存在文件,是否断点续传?
",vbyesno+vbquestion,"提示")
ifconfirm=vbyesthen
downposition=""
ifnotofilectrl.readkeyfromini("update","downsize",apppath+"update.ini",downposition)then
读取上次下载的字节数
msgbox"读取大小错误",vbinformation,"提示"
endif
发送断点续传请求
strcommand=strcommand&"range:
bytes="&clng(downposition)&"-"&vbcrlf
else
killsavefilename删除原文件
endif
endif
strcommand=strcommand&"connection:
keep-alive"&vbcrlf
strcommand=strcommand&vbcrlf
.senddatastrcommand
endwith
iferrthen
lblprocessresult.caption=lblprocessresult.caption&vbcrlf&vbcrlf&"下载文件出错:
"&err.description
lblprocessresult.refresh
endif
endsub
第二步,具体实现代码步骤2:
接收数据
--------------------------------------------------------------------------------
name:
winsck_dataarrival
author:
reker2004/3/20
desc:
略
params:
略
return:
none
history:
none
--------------------------------------------------------------------------------
privatesubwinsck_dataarrival(byvalbytestotalaslong)
onerrorresumenext
doevents:
doevents
dimbytedata()asbyte
winsck.getdatabytedata(),vbbyte
receivedata=receivedata&strconv(bytedata(),vbunicode)
ifinstr(1,receivedata,"content-length:
")>0andfilesize=0then仅第一次计算,filesize=0
dimpos1aslong,pos2aslong
pos1=instr(1,receivedata,"content-length:
")
pos2=instr(pos1+16,receivedata,vbcrlf)
ifpos2>pos1then
filesizebyte=mid(receivedata,pos1+16,pos2-pos1-16)计算文件的长度
starttime=timer()保存开始下载的时间
progssbar.max=filesizebyte设置进度条
filesize=formatnumber(filesizebyte/1024,2)以kb表示
showinfo"本次下载的文件共"+cstr(filesize)+"kb..."
endif
endif
从服务器响应返回的数据查找下载文件的起始位置
iffileheaderlen=0then
fori=0toubound(bytedata())-3
ifbytedata(i)=13andbytedata(i+1)=10andbytedata(i+2)=13andbytedata(i+3)=10then
startpos=i+4将文件头的长度保存下来
fileheaderlen=startpos
exitfor
endif
doevents
nexti
endif
filesizehavedown=bytestotal+filesizehavedown-fileheaderlen
已下载文件长度,需减去响应的文件头长度
dbldownloadspeed=formatnumber(formatnumber(filesizehavedown/1024,2)/(formatnumber((timer()-starttime),4)),2)计算下载速率kb/s
ifdbldownloadspeed<>0then计算剩余下载的时间
sresttime=getresttime(clng((filesize-(filesizehavedown)/1024)/dbldownloadspeed))此过程略,可以删除此段代码
labresttime.caption="剩余时间:
º"+sresttime
labresttime.refresh
endif
labdownloadspeed.caption=cstr(dbldownloadspeed)+"kb/s"
labdownloadspeed.refresh
progssbar.value=filesizehavedown
写数据
fnum=freefile()
opensavefilenameforbinarylockwriteas#fnum
iflof(fnum)>0then
seek#fnum,lof(fnum)+1
endif
ifstartpos>0then
fori=startpostoubound(bytedata())
put#fnum,,bytedata(i)
nexti
else
put#fnum,,bytedata()
endif
close#fnum
iferrthen
lblprocessresult.caption=lblprocessresult.caption&vbcrlf&获取数据出错:
"&err.description
lblprocessresult.refresh
endif
endsub
[VB]VB在线更新程序示例,支持.zip自解压缩(2006-11-2423:
52:
00)
【收藏】【评论】【打印】【关闭】
标签:
VB 在线更新 程序 示例 解压缩
用VB帮星河霸业游戏团队的《第二天堂》游戏写的一个在线更新程序,自动判断是否需要更新,支持多文件更新,并支持.zip压缩文件更新,自动将.zip压缩文件解压到目录下。
源代码下载:
VB_OnlineUpdateInet.rar
其中:
ClientInfor.inf文件:
第一行的数据表示:
客户端游戏版本号
第一行的数据表示:
更新文件存放的网络路径
UpdateInfor.inf文件:
第一行的数据表示:
最新游戏版本号
第二行的数据表示:
有多少文件需要更新
后面每行的数据表示:
需要更新的文件的名称
frmUpdate.frm窗体:
负责下载
modZip.BAS模块:
只负责用来压缩文件和解压缩文件的
其中的UnZipTo 函数用来解压缩的
zlib.dll:
为WinZip的dll文件
更新完毕后,ClientInfor.inf文件的第一行的数据会变为最新版本号
frmUpdate.frm窗体代码如下:
PrivateSubcmdExit_Click()
UnloadMe
EndSub
PrivateSubcmdUpdate_Click()
DimstrClientInfor()AsString
DimstrUpdateInfor()AsString
DimnNumAsInteger '存储更新到第几个文件
'出错则跳出更新,并提示给用户
OnErrorGoToErrMsg
strClientInfor()=getClientInfor
strUpdateInfor()=getUpdateInfor(strClientInfor
(1))
inetOLUpdate.RequestTimeout=0 '以验证客户可以连接到服务器,后面更新将不在设置请求超时
nNum=0
DimverClientAsDouble
DimverUpdateAsDouble
DimstrName AsVariant
DimbArray() AsByte
DimnI AsInteger
DimstrFlag AsString '保存后缀名
verClient=strClientInfor(0) '获得客户端游戏版本号
verUpdate=strUpdateInfor(0) '获得最新游戏版本号
IfverClient
IfMsgBox("已出最新版,是否更新游戏",vbInformation+vbYesNo,"在线更新")=vbYesThen
'设置进度条
timUpdate.Enabled=True
proUpdate.Max=CInt(strUpdateInfor
(1))
proUpdate.Min=0
'更新游戏
FornI=2ToCInt(strUpdateInfor
(1))+1
'显示正在更新第几个文件,以及更新文件总数
lblNumber.Caption="文件更新("&(nI-1)&"/"&CInt(strUpdateInfor
(1))&")"
'读取服务器更新文件,并保存到客户端
bArray()=inetOLUpdate.OpenURL(strClientInfor
(1)+"/"+strUpdateInfor(nI),icByteArray)
OpenApp.Path+"\"+strUpdateInfor(nI)ForBinaryAccessWriteAs#1
Put#1,,bArray()
Close#1
nNum=nI-1 '存储更新到第几个文件
proUpdate.Value=nNum '更新进度条
lblScale.Caption=(proUpdate.Value/proUpdate.Max)*100&"%" '显示更新比例
NextnI
'减压.zip文件
FornI=2ToCInt(strUpdateInfor
(1))+1
strFlag=Mid(strUpdateInfor(nI),InStr(strUpdateInfor(nI),".")+1)'获得后缀名
IfstrFlag="zip"Then '判断该文件是否为.zip压缩文件
UnZipToApp.Path,App.Path+"\"+strUpdateInfor(nI) '解压缩
KillApp.Path+"\"+strUpdateInfor(nI) '删除压缩文件
EndIf
NextnI
'更新客户端信息文件UpdateInfor.inf
updateClientInforstrUpdateInfor(0),strClientInfor
(1)
MsgBox"游戏更新完毕,谢谢你的支持!
",vbInformation+vbOKOnly,"在线更新"
UnloadMe '结束在线更新
EndIf
Else
MsgBox"已是最新版,不需要更新!
",vbInformation+vbOKOnly
UnloadMe '结束在线更新
EndIf
ExitSub
ErrMsg:
MsgBox"游戏更新出错,请重新启动游戏更新",vbCritical+vbOKOnly,"在线更新"
EndSub
PrivateSubForm_Load()
inetOLUpdate.RequestTimeout=15 '请求连接超过15秒,则退出连接
EndSub
'获得客户端游戏版本号和服务器路径信息
PublicFunctiongetClientInfor()AsVariant
DimstrInfor(10) AsString
DimstrTest AsString
DimnI AsInteger
nI=0
OpenApp.Path+"/ClientInfor.inf"ForInputAs#1 '打开ClientInfor.inf
DoWhileNotEOF
(1) '获得客户端的游戏版本和服务器路径 信息
LineInput#1,strInfor(nI)
nI=nI+1
Loop
Close#1
getClientInfor=strInfor()
EndFunction
'获得更新文件信息
'strPath为更新文件在网上的地址
PublicFunctiongetUpdateInfor(strPathAsString)AsVariant
DimstrInfor(20) AsString
DimnI AsInteger
DimbArray() AsByte
'读取服务器更新文件的信息,并保存到客户端
bArray()=inetOLUpdate.OpenURL(strPath+"/UpdateInfor.inf",icByteArray)
'Kill"UpdateInfor.inf" '删除原有更新文件
OpenApp.Path+"/UpdateInfor.inf"ForBinaryAccessWriteAs#1
Put#1,,bArray()
Close#1
nI=0
OpenApp.Path+"/UpdateInfor.inf"ForInputAs#1 '打开ServerInfor.inf
DoWhileNotEOF
(1) '获得最新的游戏版本和更新文件的路径
LineInput#1,strInfor(nI)
nI=nI+1
Loop
Close#1
getUpdateInfor=strInfor()
EndFunction
'更新客户端信息文件UpdateInfor.inf
PublicFunctionupdateClientInfor(strVersionAsString,strWebPathAsString)AsBoolean
OpenApp.Path+"/ClientInfor.inf"ForOutputAs#1
Print#1,strVersion
Print#1,strWebPath
Close#1
EndFunction
modZip.BAS模块代码如下:
只负责用来压缩文件和解压缩文件的(可以不看)